簡體   English   中英

解析JSON,然后將多個字符串添加到ArrayList

[英]Parsing JSON then adding multiple strings to an ArrayList

當前正在開發一個應用程序,該應用程序從搜索中獲取結果,解析返回的JSON對象,然后將結果片段添加到創建的名為VenueList的類中的幾個ArrayLists中。

這是從服務接收結果並解析JSON的方法:

 private static List<String> getResultsFromJson(String json) {
    ArrayList<String> resultList = new ArrayList<String>();         
    try {
        JSONObject resultsWrapper = (JSONObject) new JSONTokener(json).nextValue(); 
        JSONArray  results        = resultsWrapper.getJSONArray("results");

        for (int i = 0; i < results.length(); i++) {
            JSONObject result = results.getJSONObject(i);
            resultList.add(result.getString("text")); 

        }
    }
    catch (JSONException e) {
        Log.e(TAG, "Failed to parse JSON.", e);
    }

    return resultList;
}

其結果將成為List變量,調用mResults (以澄清: mResults = getResultsFromJson(restResult);然后在以下循環中將其用於其他地方,該循環將結果放入ArrayAdapter ,該ArrayAdapter用於將結果顯示在ListFragment:

for (String result : mResults) {    
    VenueList.addVenue(result, "HELLO WORLD"); 
    adapter.add(result);
}

我還將結果添加到名為VenueList的類中,該類管理結果並使它們可用於多個視圖。 實際上,它僅包含多個ArrayLists ,這些ArrayLists包含搜索中返回的每個場所的不同類型的詳細信息。 我在VenueList添加場所的方法如下(您可以在上面的for循環中看到它):

public static void addVenue(String name, String geo) {
    venueNames.add(name);
    venueGeos.add(geo);
}

我希望addVenue方法能夠采用多個參數並更新VenueList類。 但是,當我在for循環中調用addVenue方法時,我只能將其傳遞給String result (來自循環的參數),而無法弄清楚如何將其傳遞給第二個參數(也應來自解析后的JSON)由getResultsFromJson ),所以我現在已經使用"HELLO WORLD"作為占位符。

我意識到getResultsFromJson僅返回一個列表。 我需要能夠從解析的JSON對象中獲取多個元素,然后以正確的順序將它們添加到VenueList中。

所以我的問題是:

1)給定getResultsFromJson方法和for循環,如何使用設計的addVenue()方法? 如何解析JSON中的多個元素,然后將它們同時添加到VenueList? 我計划稍后再添加更多參數,但是我假設如果可以使它與兩個一起工作,那么可以使其與四個或五個一起工作。

2)如果不可能,應該如何重新設計getResultsFromJsonfor循環和addVenue方法以使其正常工作?

如果您需要更多詳細信息或代碼,請告訴我-我們樂意提供。 謝謝!

編輯-完整的VenueList類:

public class VenueList {

private static ArrayList<String> venueNames; 
private static ArrayList<String> venueGeos;

public VenueList() {
    venueNames = new ArrayList<String>();
    venueGeos = new ArrayList<String>();
}

public static void addVenue(String name, String geo) { 
    venueNames.add(name);
    venueGeos.add(geo);
}

public static String getVenueName(int position) { 
    return venueNames.get(position);
}

public static String getVenueGeo(int position) {
    return venueGeos.get(position);
}

public static void clearList() {
    venueNames.clear();
    venueGeos.clear();
}

}

澄清:對於要存儲的有關場地的每個數據元素,我將具有附加的ArrayList(電話號碼,地址等)

1)我認為方法getResultsFromJson(String json)和addVenue(String name,String geo)都不適合您的需求。

2)我會考慮將方法getResultsFromJson(String json)重寫為如下形式:

private static SortedMap<Integer, List<String>> getResultsFromJson(String json) {
    Map<Integer, String> resultMap = new TreeMap<Integer, String>();         

    //...

    return resultMap;
}

其中地圖的鍵數應等於要提取信息的對象數,並且它們中的每一個都將按照正確的順序正確地擁有自己的項目列表。

通過這種方法,您當然可以將邏輯更改為以下形式:

// grab your retuned map and get an entrySet, the just iterate trough it
SortedMap<Integer, String> result = returnedMap.entrySet();

for (Entry<Integer, String> result : entrySet) {    
    Integer key = result.getKey(); // use it if you need it
    List<String> yourDesiredItems = result.getValue(); // explicitly shown to know how to get it

    VenueList.addVenue(yourDesiredItems); 
}

public static void addVenue(List<String> yourDesiredItems) {
    // refactor here to iterate the items trough the list and save properly    

    //....
}

編輯-因為您希望避免中間地圖,所以我假設您不需要從該方法返回任何內容

首先,我為您提供了滿足您要求的解決方案,然后為您提供了一些提示,因為我看到了一些可以簡化您的設計的事情。

要直接從getResultsFromJSON保存VenueList內容,請執行以下操作:

private static void getResultsFromJson(String json) {
    try {
        JSONObject resultsWrapper = (JSONObject) new JSONTokener(json).nextValue(); 
        JSONArray  results        = resultsWrapper.getJSONArray("results");

        for (int i = 0; i < results.length(); i++) {
            JSONObject result = results.getJSONObject(i);

            //FOR EXAMPLE HERE IS WHERE YOU NEED TO EXTRACT INFO
            String name = result.getString("name");
            String geo = result.getString("geo");

            // and then...

            VenueList.addVenue(name, geo, ..., etc);
        }
    } catch (JSONException e) {
        Log.e(TAG, "Failed to parse JSON.", e);
    }
}

這意味着您的addVenue方法應該知道接收所有需要的參數。 如您所見,這只是一種方式(可以考慮解決您的需求),但是由於我不知道會導致您對此模型進行編碼的所有要求,因此我將指出一些您可能會考慮的事項:

1. 如果VenueList類有理由使用所有靜態內容,請考慮這樣做:

static{
    venueNames = new ArrayList<String>();
    venueGeos = new ArrayList<String>();
    //....
}

private VenueList(){
}

這樣,您無需每次都獲取實例,並且在執行VenueList.addVenue(...)無需事先實例化就可以避免null pointer exceptions

2. 不要為VenueList類中的每個特征都擁有一個ArrayList ,而是考慮為Venue定義一個model object ,如下所示:

public class Venue{
    String name;
    String geo;
    //... etc

    public Venue(){
    }

    // ... getters & setters
}

然后,如果您需要該VenueList類,那么您將只具有一個Venue對象(List<Venue>) ,這意味着您addVenue創建方法addVenue ,而是先創建一個全新的Venue類實例,然后調用setter方法每個特性的一個例子,作為我提供的替代方法的重構for循環的示例,您將使用如下所示的內容:

List<Venue> myListOfVenues = new ArrayList<Venue>();

for (int i = 0; i < results.length(); i++) {
    JSONObject result = results.getJSONObject(i);

    // THIS WOULD REMAIN THE SAME TO EXTRACT INFO
    String name = result.getString("name");
    String geo = result.getString("geo");

    // and then instead of calling VenueList.addVenue(name, geo, ..., etc)...
    Venue v = new Venue();
    v.setName(name);
    v.setGeo(geo);
    // ...etc

    myListOfVenues.add(v);
}

// Once you're done, set that List to VenueList class
VenueList.setVenueList(myListOfVenues);

因此, VenueList類現在將具有單個屬性List<Venue> venueList; 並會在方法getVenueName, etc...getVenueName, etc...並且所有內容都將更具可讀性……我希望這可以幫助您找到另一種方法來解決您的問題,如果我仍然不明白我的意思的話,會盡力幫助您...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM