【问题标题】:How to iterate over a JSONObject?如何遍历 JSONObject?
【发布时间】:2012-02-27 10:14:25
【问题描述】:

我使用一个名为 JSONObject 的 JSON 库(如果需要,我不介意切换)。

我知道如何遍历 JSONArrays,但是当我从 Facebook 解析 JSON 数据时,我没有得到一个数组,只有一个 JSONObject,但我需要能够通过它的索引访问一个项目,例如作为JSONObject[0]获得第一个,我不知道该怎么做。

{
   "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
   }
}

【问题讨论】:

标签: java json


【解决方案1】:

也许这会有所帮助:

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      
    }
}

【讨论】:

  • 大家小心,jObject.keys() 返回的迭代器是反向索引顺序的。
  • @macio.Jun 尽管如此,属性映射中的顺序并不重要:JSONObject 中的键是无序的,您的断言是私有实现的简单反映;)
  • 按顺序需要所有键时使用什么?
  • 小问题:这不会导致两次密钥查找吗?可能最好做'Object o = jObject.get(key)',然后检查它的类型然后使用它,而不必再次调用get(key)。
  • 我想提一下,对于那些有“keys()”方法没有得到解决问题的人(说 JSONObject 没有那个方法):你可以输入 @987654323 @ 并且它工作正常。
【解决方案2】:

对于我的情况,我发现迭代 names() 效果很好

for(int i = 0; i<jobject.names().length(); i++){
    Log.v(TAG, "key = " + jobject.names().getString(i) + " value = " + jobject.get(jobject.names().getString(i)));
}

【讨论】:

  • 虽然这个例子在Java中并不能真正理解为Iterating,但它运行得很好!谢谢。
  • 很好的答案。它适用于几乎所有类型的嵌套或不嵌套的 json 对象。 !
  • 什么是Log. v() ?它属于哪个库?
  • @tarekahf Android SDK
【解决方案3】:

我将避免使用迭代器,因为它们可以在迭代期间添加/删除对象,也可以用于干净的代码使用 for 循环。它会简单干净且行数更少。

使用 Java 8 和 Lamda [2019 年 4 月 2 日更新]

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);
    });
}

使用旧方法 [2019 年 4 月 2 日更新]

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);
    }
}

原答案

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);
    }
}

【讨论】:

  • 他们从未说过他们在使用 org.json.simple(这是一个谷歌库)。不幸的是,标准 org.json.JSONObject 迫使您使用迭代器。
  • 你救了我的但在这里!
  • org.json.JSONObject 没有 keySet()
  • 不错的答案。很容易被选项宠坏。 :) 所有选项都完美无缺。太棒了。
【解决方案4】:

不敢相信没有比在这个答案中使用迭代器更简单和安全的解决方案了...

JSONObject names () 方法返回 JSONArrayJSONObject 键,因此您可以简单地循环遍历它:

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
   
}

【讨论】:

  • 这里的对象是什么?
  • 它是JSONObject。像JSONObject object = new JSONObject ("{\"key1\",\"value1\"}"); 这样的东西。但不要将原始 json 放入其中,使用 put () 方法在其中添加项目:object.put ("key1", "value1");
  • 谢谢先生,对我很有帮助
  • @GanesanJ 很高兴听到它)
  • 这是迄今为止最干净的答案,+1
【解决方案5】:
Iterator<JSONObject> iterator = jsonObject.values().iterator();

while (iterator.hasNext()) {
 jsonChildObject = iterator.next();

 // Do whatever you want with jsonChildObject 

  String id = (String) jsonChildObject.get("id");
}

【讨论】:

  • jsonChildObject = iterator.next(); 应该定义jsonChildObject,就像JSONObject jsonChildObject = iterator.next();,不是吗?
  • 我喜欢这个解决方案,但声明 Iterator&lt;JSONObject&gt; 会发出警告。我会用通用的&lt;?&gt; 替换它,并对next() 的调用进行强制转换。另外,我会使用 getString("id") 而不是 get("id") 来节省演员。
【解决方案6】:

org.json.JSONObject 现在有一个 keySet() 方法,它返回一个 Set&lt;String&gt; 并且可以很容易地用 for-each 循环。

for(String key : jsonObject.keySet())

【讨论】:

  • 我认为这是最方便的解决方案。感谢您的建议:)
  • 你能完成你的例子吗?
【解决方案7】:

这里的大多数答案都是针对扁平 JSON 结构的,如果您的 JSON 可能具有嵌套的 JSONArrays 或 Nested JSONObjects,那么真正的复杂性就会出现。以下代码 sn-p 负责处理此类业务需求。它需要一个哈希映射,以及带有嵌套 JSONArrays 和 JSONObjects 的分层 JSON,并使用哈希映射中的数据更新 JSON

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));
            }
        }
    });

}

这里你必须注意 this 的返回类型是 void,但是 sice 对象作为引用被传递,这个变化被反映给调用者。

【讨论】:

    【解决方案8】:

    首先把它放在某个地方:

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

    或者,如果您可以访问 Java8,则只需:

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

    然后简单地遍历对象的键和值:

    for (String key : iteratorToIterable(object.keys())) {
        JSONObject entry = object.getJSONObject(key);
        // ...
    

    【讨论】:

    • 我对此投了赞成票,但“String key : ....”无法编译,而且似乎没有办法避免迭代器上出现未经检查的强制转换警告。愚蠢的迭代器。
    【解决方案9】:

    我做了一个小的递归函数,它遍历整个 json 对象并保存键路径及其值。

    // 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();
        }
    }
    

    【讨论】:

      【解决方案10】:

      使用 Java 8 和 lambda,更简洁:

      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-

      【讨论】:

      • 它只迭代键但你仍然需要获取值,所以你可以使用 jObject.get(k);
      • 我得到“从 null 转换为消费者需要最低 API 24”
      【解决方案11】:

      我们使用下面的代码集来迭代 JSONObject 字段

      Iterator iterator = jsonObject.entrySet().iterator();
      
      while (iterator.hasNext())  {
              Entry<String, JsonElement> entry = (Entry<String, JsonElement>) iterator.next();
              processedJsonObject.add(entry.getKey(), entry.getValue());
      }
      

      【讨论】:

        【解决方案12】:

        我曾经有一个 json,它的 id 需要加一,因为它们是 0 索引的,这破坏了 Mysql 的自动增量。

        因此,我为每个对象编写了这段代码 - 可能对某人有所帮助:

        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);
                            }
                        }
                    }
                }
            }
        

        用法:

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

        这也可以转换为 JSONArray 作为父对象工作

        【讨论】:

          【解决方案13】:

          我做了我的小方法来记录 JsonObject 字段,并得到一些刺痛。看看有没有用。

          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
          }
          }
          

          【讨论】:

            【解决方案14】:

            下面的代码对我来说很好用。如果可以进行调整,请帮助我。这甚至可以从嵌套的 JSON 对象中获取所有键。

            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;
            }
            

            【讨论】:

              【解决方案15】:

              这是该问题的另一个有效解决方案:

              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();
                  }
              }
              

              【讨论】:

                【解决方案16】:

                更简单的方法是(刚刚在 W3Schools 上找到):

                let data = {.....}; // JSON Object
                for(let d in data){
                    console.log(d); // It gives you property name
                    console.log(data[d]); // And this gives you its value
                }
                

                更新

                在您处理嵌套对象之前,这种方法可以正常工作,因此这种方法可以正常工作。

                const iterateJSON = (jsonObject, output = {}) => {
                  for (let d in jsonObject) {
                    if (typeof jsonObject[d] === "string") {
                      output[d] = jsonObject[d];
                    }
                    if (typeof jsonObject[d] === "object") {
                      output[d] = iterateJSON(jsonObject[d]);
                    }
                  }
                  return output;
                }
                

                并使用这样的方法

                let output = iterateJSON(your_json_object);
                

                【讨论】:

                • 请密切关注标签。 OP 需要 Java 中的解决方案,而不是 JavaScript!
                猜你喜欢
                • 1970-01-01
                • 2011-05-27
                • 2021-05-28
                • 1970-01-01
                • 1970-01-01
                • 2022-08-10
                • 2014-08-13
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多