简体   繁体   中英

Parse JSON using Iterator and set it in listview accordingly

I'm developing an application is which I have a JSON response, which looks like this:

{
"notifications":{
  "0":{
      "text":"First One",
      "state":"new"
   },
  "1":{
      "text":"Second One",
      "state":"new"
   },
  "2":{
      "text":"Third One",
       "state":"new"
   },
  "3":{
      "text":"Fourth One",
      "state":"old"
   },
  "4":{
      "text":"Fifith One",
      "state":"old"
   }
 }
}

I'm using Iterator class to parse this response. I'm doing something like this:

notifyList = new ArrayList<HashMap<String, String>>();
try {
    JSONObject rootObj = new JSONObject(result);
    JSONObject jSearchData = rootObj.getJSONObject("notifications");

    Iterator<String> keys = jSearchData.keys();
    while (keys.hasNext()) {
        String key = keys.next();
        JSONObject jNotification0 = jSearchData.optJSONObject(key);

        if (jNotification0 != null) {

            String text = jNotification0.getString("text");
            String state = jNotification0.getString("state");

            HashMap<String, String> map = new HashMap<String, String>();
                            map.put("text", text);
            map.put("state", state);

            System.out.println("Text: " + text);
            System.out.println("State: " + state);

            notifyList.add(map);


            }
            else { 
        }

But this gives me data in jumbled format, it is not coming like wise as it is in JSON response.

Here is the log which prints, which is all jumbled:

Text: Fourth One
State: old
Text: Third One
State: new
Text: Second One
State: new
Text: First One
State: new
Text: Fifth One
State: old

I was just using "state" variable and sorting it accordingly so that my "new" state comes first before "old state". But this is not helping me if I have 2-3 new state in my response.

I have tried collections code which look something like this:

Collections.sort(notifyList,
                    new Comparator<Map<String, String>>() {
                        @Override
                        public int compare(final Map<String, String> map1,
                                final Map<String, String> map2) {
                            int comparison = map1.get("state")
                                    .compareToIgnoreCase(map2.get("state"));

                            if (comparison == 0)
                                return 0;

                            else if (comparison > 0)
                                return 1;

                            else
                                return -1;
                        }
                    }

            );

Any idea how to solve this problem I want to show the response order wise?

Any kind of help will be appreciated.

I suggest replacing the "1", "2", ... values into Json Array, so that it will look like:

{
 "notifications":[
    {
      "text":"First One",
      "state":"new"
    },
    {
      "text":"Second One",
      "state":"new"
    },
    {
      "text":"Third One",
      "state":"new"
    },
    {
      "text":"Fourth One",
      "state":"old"
    },
    {
      "text":"Fifith One",
      "state":"old"
  }
 ]
}

This way you can iterate over the array without being concerned about elements order

First: your map is wrong. You're putting key/values this way:

key       |     value
---------------------------
text      |   First One
state     |   new
text      |   second one
state     |   new
text      |   Third one
state     |   new
text      |   Fourth one
state     |   old

So all the values will be overriden (you are putting them with the same keys).

Second: You need a comparator for String , not Map<String, String> .

List<String> sortedKeys = new ArrayList<>();
sortedKeys.addAll(map.keySet()); //sorted keys will hold all keys for the map
Collection.sort(
    sortedKeys,
    new Comparator<String>(){

         int compare(String s1, String s2) {
             return comparison = map.get(s1)
                 .compareToIgnoreCase(map.get(s2));
         }
    });
//here you'll have sortedKeys - with keys sorted by the state.
// just get the values from the map iterating it the sortedKeys.

Your data seems that should be in an array format. However as a workaround and if you are always going to get numbers as the keys, then you could create a helper class Notification . that would have 3 fields: key , text , state . Instead of returning a List of Map you would return a List<Notification>

notifyList = new ArrayList<Notification>();
while (...) {
   ...
   String text = jNotification0.getString("text");
   String state = jNotification0.getString("state");

   Notification notification = new Notification(key, text, state);
   notifyList.add(notification);
}

You could then use a Comparator to sort by the key field to get the same order as in the text or any combination between state and key you like (eg first order by state by keeping the same order for items within the same state)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM