如何迭代一个JSONObject?

我使用一个名为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
}
}
764675 次浏览

也许这个会有帮助:

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
}
}
Iterator<JSONObject> iterator = jsonObject.values().iterator();


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


// Do whatever you want with jsonChildObject


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

对于我的情况下,我发现迭代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)));
}

我做了一个小的递归函数,遍历整个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();
}
}

我将避免迭代器,因为它们可以在迭代过程中添加/删除对象,也可以为循环使用干净的代码。它将是简单的清洁&更少的线。

使用Java 8和Lamda[更新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);
});
}

使用旧方式[更新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);
}
}

原来的答案

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

首先把这个放在某个地方:

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);
// ...

使用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-

我曾经有一个json,有id需要加1,因为他们是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作为父对象

不敢相信在这个答案中没有更简单和安全的解决方案,而不是使用迭代器…

JSONObject names ()方法返回JSONObject键的JSONArray,所以你可以简单地在循环中遍历它:

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
   

}

org.json.JSONObject现在有一个keySet()方法,该方法返回Set<String>,可以很容易地使用for-each循环。

for(String key : jsonObject.keySet())

下面的代码对我来说很好。如果可以调音,请帮助我。这甚至可以从嵌套的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;
}

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

Iterator iterator = jsonObject.entrySet().iterator();


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

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

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

这里的大多数答案都是扁平的JSON结构,如果你有一个JSON,可能有嵌套的JSONArrays或嵌套的JSONObjects,真正的复杂性就出现了。下面的代码片段处理这样的业务需求。它接受一个哈希映射和带有嵌套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对象作为引用传递,此更改反映给调用者。

我让我的小方法记录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
}
}