414

I use a JSON library called JSONObject (I don't mind switching if I need to).

I know how to iterate over JSONArrays, but when I parse JSON data from Facebook I don't get an array, only a JSONObject, but I need to be able to access an item via its index, such as JSONObject[0] to get the first one, and I can't figure out how to do it.

{
 "http://http://url.com/": {
 "id": "http://http://url.com//"
 },
 "http://url2.co/": {
 "id": "http://url2.com//",
 "shares": 16
 }
 ,
 "http://url3.com/": {
 "id": "http://url3.com//",
 "shares": 16
 }
}
Willi Mentzel
30.2k21 gold badges120 silver badges129 bronze badges
asked Feb 5, 2012 at 18:06
2

16 Answers 16

698

Maybe this will help:

JSONObject jsonObject = new JSONObject(contents.trim());
Iterator<String> keys = jsonObject.keys();
while(keys.hasNext()) {
 String key = keys.next();
 if (jsonObject.get(key) instanceof JSONObject) {
 // do something with jsonObject here 
 }
}
Aramis NSR
1,8981 gold badge21 silver badges27 bronze badges
answered May 15, 2012 at 3:36
Sign up to request clarification or add additional context in comments.

8 Comments

Be careful everyone, jObject.keys() returns the iterator with reverse index order.
@macio.Jun Nevertheless, the order doesn't matter in maps of properties: keys in JSONObject are unordered and your assertion was a simple reflection of a private implementation ;)
What to use when we need all keys sequentially ?
Slight quibble: doesn't this lead to doing the key lookup twice? Maybe better to do 'Object o = jObject.get(key)', then check its type and then use it, without having to call get(key) again.
I would just like to mention, for people that have the problem of "keys()" method not getting resolved (saying that the JSONObject doesn't have that method): you can instead type jsonObject.keySet().iterator() and it works fine.
|
107

for my case i found iterating the names() works well

for(int i = 0; i<jobject.names().length(); i++){
 Log.v(TAG, "key = " + jobject.names().getString(i) + " value = " + jobject.get(jobject.names().getString(i)));
}
answered Sep 22, 2014 at 14:49

4 Comments

Although this example isn't really understood as Iterating in Java, it works quite well! Thanks.
Great answer. It works perfectly for almost all types of json objects nested or not. !
What is Log. v() ? Which library it belongs to?
@tarekahf Android SDK
86

I will avoid iterator as they can add/remove object during iteration, also for clean code use for loop. it will be simply clean & fewer lines.

Using Java 8 and Lamda [Update 4/2/2019]

import org.json.JSONObject;
public static void printJsonObject(JSONObject jsonObj) {
 jsonObj.keySet().forEach(keyStr ->
 {
 Object keyvalue = jsonObj.get(keyStr);
 System.out.println("key: "+ keyStr + " value: " + keyvalue);
 //for nested objects iteration if required
 //if (keyvalue instanceof JSONObject)
 // printJsonObject((JSONObject)keyvalue);
 });
}

Using old way [Update 4/2/2019]

import org.json.JSONObject;
public static void printJsonObject(JSONObject jsonObj) {
 for (String keyStr : jsonObj.keySet()) {
 Object keyvalue = jsonObj.get(keyStr);
 //Print key and value
 System.out.println("key: "+ keyStr + " value: " + keyvalue);
 //for nested objects iteration if required
 //if (keyvalue instanceof JSONObject)
 // printJsonObject((JSONObject)keyvalue);
 }
}

Original Answer

import org.json.simple.JSONObject;
public static void printJsonObject(JSONObject jsonObj) {
 for (Object key : jsonObj.keySet()) {
 //based on you key types
 String keyStr = (String)key;
 Object keyvalue = jsonObj.get(keyStr);
 //Print key and value
 System.out.println("key: "+ keyStr + " value: " + keyvalue);
 //for nested objects iteration if required
 if (keyvalue instanceof JSONObject)
 printJsonObject((JSONObject)keyvalue);
 }
}
answered Sep 5, 2015 at 11:25

5 Comments

They never said they were using org.json.simple (which is a google library). The standard org.json.JSONObject forces you to use an iterator, unfortunately.
org.json.JSONObject does not have keySet()
Nice answer. Easy to get spoiled by options. :) All options just work flawlessly. Brilliant.
Nice use of recursion. I used a similar pattern, adding JSONArray testing to it, including JSONObject recursion within the array elements. The String became the fall-thru case.
81

Can't believe that there is no more simple and secured solution instead of using an iterator in this answers...

JSONObject names () method returns a JSONArray of the JSONObject keys, so you can simply walk though it in loop:

JSONObject object = new JSONObject ();
JSONArray keys = object.names ();
for (int i = 0; i < keys.length (); i++) {
 
 String key = keys.getString (i); // Here's your key
 String value = object.getString (key); // Here's your value
 
}
answered Nov 12, 2017 at 19:21

6 Comments

what is object here?
It's JSONObject. Something like JSONObject object = new JSONObject ("{\"key1\",\"value1\"}");. But do not put raw json to it, add items in it with put () method: object.put ("key1", "value1");.
@GanesanJ glad to hear it)
This is by far the cleanest answer, +1
still unordered :((
|
19
Iterator<JSONObject> iterator = jsonObject.values().iterator();
while (iterator.hasNext()) {
 jsonChildObject = iterator.next();
 // Do whatever you want with jsonChildObject 
 String id = (String) jsonChildObject.get("id");
}
Luke
20.4k16 gold badges111 silver badges121 bronze badges
answered May 26, 2014 at 13:02

2 Comments

jsonChildObject = iterator.next(); should probably define jsonChildObject, like JSONObject jsonChildObject = iterator.next();, no?
I like this solution, but declaring Iterator<JSONObject> will give a warning. I'd replace it with the generic <?> and do a cast on the call to next(). Also, I'd use getString("id") instead of get("id") to save doing a cast.
15

org.json.JSONObject now has a keySet() method which returns a Set<String> and can easily be looped through with a for-each.

for(String key : jsonObject.keySet())
answered Jan 11, 2018 at 22:06

2 Comments

I think this is the most convenient solution. Thanks for advice :)
Could you complete your example?
11

Most of the answers here are for flat JSON structures, in case you have a JSON which might have nested JSONArrays or Nested JSONObjects, the real complexity arises. The following code snippet takes care of such a business requirement. It takes a hash map, and hierarchical JSON with both nested JSONArrays and JSONObjects and updates the JSON with the data in the hash map

public void updateData(JSONObject fullResponse, HashMap<String, String> mapToUpdate) {
 fullResponse.keySet().forEach(keyStr -> {
 Object keyvalue = fullResponse.get(keyStr);
 if (keyvalue instanceof JSONArray) {
 updateData(((JSONArray) keyvalue).getJSONObject(0), mapToUpdate);
 } else if (keyvalue instanceof JSONObject) {
 updateData((JSONObject) keyvalue, mapToUpdate);
 } else {
 // System.out.println("key: " + keyStr + " value: " + keyvalue);
 if (mapToUpdate.containsKey(keyStr)) {
 fullResponse.put(keyStr, mapToUpdate.get(keyStr));
 }
 }
 });
}

You have to notice here that the return type of this is void, but sice objects are passed as refernce this change is refelected to the caller.

answered Jan 29, 2020 at 11:30

1 Comment

This should be a much higher ranked answer. The key point is to recursively iterate through both JSONArray and JSONObject items as well as simple values such as strings and numbers.
7

First put this somewhere:

private <T> Iterable<T> iteratorToIterable(final Iterator<T> iterator) {
 return new Iterable<T>() {
 @Override
 public Iterator<T> iterator() {
 return iterator;
 }
 };
}

Or if you have access to Java8, just this:

private <T> Iterable<T> iteratorToIterable(Iterator<T> iterator) {
 return () -> iterator;
}

Then simply iterate over the object's keys and values:

for (String key : iteratorToIterable(object.keys())) {
 JSONObject entry = object.getJSONObject(key);
 // ...
answered Feb 19, 2016 at 23:43

1 Comment

I voted for this, but "String key : ...." doesn't compile, and there doesn't seem to be a way to avoid an unchecked cast warning on the iterator. Stupid iterators.
2

I made a small recursive function that goes through the entire json object and saves the key path and its value.

// My stored keys and values from the json object
HashMap<String,String> myKeyValues = new HashMap<String,String>();
// Used for constructing the path to the key in the json object
Stack<String> key_path = new Stack<String>();
// Recursive function that goes through a json object and stores 
// its key and values in the hashmap 
private void loadJson(JSONObject json){
 Iterator<?> json_keys = json.keys();
 while( json_keys.hasNext() ){
 String json_key = (String)json_keys.next();
 try{
 key_path.push(json_key);
 loadJson(json.getJSONObject(json_key));
 }catch (JSONException e){
 // Build the path to the key
 String key = "";
 for(String sub_key: key_path){
 key += sub_key+".";
 }
 key = key.substring(0,key.length()-1);
 System.out.println(key+": "+json.getString(json_key));
 key_path.pop();
 myKeyValues.put(key, json.getString(json_key));
 }
 }
 if(key_path.size() > 0){
 key_path.pop();
 }
}
answered Feb 7, 2015 at 15:46

Comments

2

With Java 8 and lambda, cleaner:

JSONObject jObject = new JSONObject(contents.trim());
jObject.keys().forEachRemaining(k ->
{
});

https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html#forEachRemaining-java.util.function.Consumer-

answered Feb 15, 2017 at 15:40

2 Comments

It iterates only the keys but you still need to get the value, so you can use jObject.get(k);
I get "Cast from null to consumer requires minimum API 24"
2

I once had a json that had ids that needed to be incremented by one since they were 0-indexed and that was breaking Mysql auto-increment.

So for each object I wrote this code - might be helpful to someone:

public static void incrementValue(JSONObject obj, List<String> keysToIncrementValue) {
 Set<String> keys = obj.keySet();
 for (String key : keys) {
 Object ob = obj.get(key);
 if (keysToIncrementValue.contains(key)) {
 obj.put(key, (Integer)obj.get(key) + 1);
 }
 if (ob instanceof JSONObject) {
 incrementValue((JSONObject) ob, keysToIncrementValue);
 }
 else if (ob instanceof JSONArray) {
 JSONArray arr = (JSONArray) ob;
 for (int i=0; i < arr.length(); i++) {
 Object arrObj = arr.get(0);
 if (arrObj instanceof JSONObject) {
 incrementValue((JSONObject) arrObj, keysToIncrementValue);
 }
 }
 }
 }
 }

usage:

JSONObject object = ....
incrementValue(object, Arrays.asList("id", "product_id", "category_id", "customer_id"));

this can be transformed to work for JSONArray as parent object too

answered Oct 8, 2017 at 16:48

Comments

2

We used below set of code to iterate over JSONObject fields

Iterator iterator = jsonObject.entrySet().iterator();
while (iterator.hasNext()) {
 Entry<String, JsonElement> entry = (Entry<String, JsonElement>) iterator.next();
 processedJsonObject.add(entry.getKey(), entry.getValue());
}
Morgan Koh
2,10728 silver badges29 bronze badges
answered Jan 4, 2019 at 5:13

Comments

1

I made my small method to log JsonObject fields, and get some stings. See if it can be usefull.

object JsonParser {
val TAG = "JsonParser"
 /**
 * parse json object
 * @param objJson
 * @return Map<String, String>
 * @throws JSONException
 */
@Throws(JSONException::class)
fun parseJson(objJson: Any?): Map<String, String> {
 val map = HashMap<String, String>()
 // If obj is a json array
 if (objJson is JSONArray) {
 for (i in 0 until objJson.length()) {
 parseJson(objJson[i])
 }
 } else if (objJson is JSONObject) {
 val it: Iterator<*> = objJson.keys()
 while (it.hasNext()) {
 val key = it.next().toString()
 // If you get an array
 when (val jobject = objJson[key]) {
 is JSONArray -> {
 Log.e(TAG, " JSONArray: $jobject")
 parseJson(jobject)
 }
 is JSONObject -> {
 Log.e(TAG, " JSONObject: $jobject")
 parseJson(jobject)
 }
 else -> {
 Log.e(TAG, " adding to map: $key $jobject")
 map[key] = jobject.toString()
 }
 }
 }
 }
 return map
}
}
answered Aug 11, 2020 at 9:23

Comments

0

Below code worked fine for me. Please help me if tuning can be done. This gets all the keys even from the nested JSON objects.

public static void main(String args[]) {
 String s = ""; // Sample JSON to be parsed
 JSONParser parser = new JSONParser();
 JSONObject obj = null;
 try {
 obj = (JSONObject) parser.parse(s);
 @SuppressWarnings("unchecked")
 List<String> parameterKeys = new ArrayList<String>(obj.keySet());
 List<String> result = null;
 List<String> keys = new ArrayList<>();
 for (String str : parameterKeys) {
 keys.add(str);
 result = this.addNestedKeys(obj, keys, str);
 }
 System.out.println(result.toString());
 } catch (ParseException e) {
 e.printStackTrace();
 }
}
public static List<String> addNestedKeys(JSONObject obj, List<String> keys, String key) {
 if (isNestedJsonAnArray(obj.get(key))) {
 JSONArray array = (JSONArray) obj.get(key);
 for (int i = 0; i < array.length(); i++) {
 try {
 JSONObject arrayObj = (JSONObject) array.get(i);
 List<String> list = new ArrayList<>(arrayObj.keySet());
 for (String s : list) {
 putNestedKeysToList(keys, key, s);
 addNestedKeys(arrayObj, keys, s);
 }
 } catch (JSONException e) {
 LOG.error("", e);
 }
 }
 } else if (isNestedJsonAnObject(obj.get(key))) {
 JSONObject arrayObj = (JSONObject) obj.get(key);
 List<String> nestedKeys = new ArrayList<>(arrayObj.keySet());
 for (String s : nestedKeys) {
 putNestedKeysToList(keys, key, s);
 addNestedKeys(arrayObj, keys, s);
 }
 }
 return keys;
}
private static void putNestedKeysToList(List<String> keys, String key, String s) {
 if (!keys.contains(key + Constants.JSON_KEY_SPLITTER + s)) {
 keys.add(key + Constants.JSON_KEY_SPLITTER + s);
 }
}
private static boolean isNestedJsonAnObject(Object object) {
 boolean bool = false;
 if (object instanceof JSONObject) {
 bool = true;
 }
 return bool;
}
private static boolean isNestedJsonAnArray(Object object) {
 boolean bool = false;
 if (object instanceof JSONArray) {
 bool = true;
 }
 return bool;
}
answered Mar 7, 2018 at 6:17

Comments

0

This is is another working solution to the problem:

public void test (){
 Map<String, String> keyValueStore = new HasMap<>();
 Stack<String> keyPath = new Stack();
 JSONObject json = new JSONObject("thisYourJsonObject");
 keyValueStore = getAllXpathAndValueFromJsonObject(json, keyValueStore, keyPath);
 for(Map.Entry<String, String> map : keyValueStore.entrySet()) {
 System.out.println(map.getKey() + ":" + map.getValue());
 } 
}
public Map<String, String> getAllXpathAndValueFromJsonObject(JSONObject json, Map<String, String> keyValueStore, Stack<String> keyPath) {
 Set<String> jsonKeys = json.keySet();
 for (Object keyO : jsonKeys) {
 String key = (String) keyO;
 keyPath.push(key);
 Object object = json.get(key);
 if (object instanceof JSONObject) {
 getAllXpathAndValueFromJsonObject((JSONObject) object, keyValueStore, keyPath);
 }
 if (object instanceof JSONArray) {
 doJsonArray((JSONArray) object, keyPath, keyValueStore, json, key);
 }
 if (object instanceof String || object instanceof Boolean || object.equals(null)) {
 String keyStr = "";
 for (String keySub : keyPath) {
 keyStr += keySub + ".";
 }
 keyStr = keyStr.substring(0, keyStr.length() - 1);
 keyPath.pop();
 keyValueStore.put(keyStr, json.get(key).toString());
 }
 }
 if (keyPath.size() > 0) {
 keyPath.pop();
 }
 return keyValueStore;
}
public void doJsonArray(JSONArray object, Stack<String> keyPath, Map<String, String> keyValueStore, JSONObject json,
 String key) {
 JSONArray arr = (JSONArray) object;
 for (int i = 0; i < arr.length(); i++) {
 keyPath.push(Integer.toString(i));
 Object obj = arr.get(i);
 if (obj instanceof JSONObject) {
 getAllXpathAndValueFromJsonObject((JSONObject) obj, keyValueStore, keyPath);
 }
 if (obj instanceof JSONArray) {
 doJsonArray((JSONArray) obj, keyPath, keyValueStore, json, key);
 }
 if (obj instanceof String || obj instanceof Boolean || obj.equals(null)) {
 String keyStr = "";
 for (String keySub : keyPath) {
 keyStr += keySub + ".";
 }
 keyStr = keyStr.substring(0, keyStr.length() - 1);
 keyPath.pop();
 keyValueStore.put(keyStr , json.get(key).toString());
 }
 }
 if (keyPath.size() > 0) {
 keyPath.pop();
 }
}
Marinos An
11.3k7 gold badges79 silver badges113 bronze badges
answered Mar 27, 2019 at 10:59

Comments

0

The easiest way is to use a for-each loop over the set of keys. Given you have a String value of JSON called "text":

JSONObject jsonObject = new JSONObject(text);
for (String key : jsonObject.keySet()) {
 // Print out each value to verify this code
 System.out.println(jsonObject.get(key));
}

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.