合并(Concat)Java中的多个JSONObjects

Dan*_*nDC 50 java json concat

我从两个不同的来源消耗了一些JSON,我最终得到两个JSONObject,我想将它们合并为一个.

数据:

"Object1": {
    "Stringkey":"StringVal",
    "ArrayKey": [Data0, Data1]
}

"Object2": {
    "Stringkey":"StringVal",
    "Stringkey":"StringVal",
    "Stringkey":"StringVal",
}
Run Code Online (Sandbox Code Playgroud)

代码,使用http://json.org/java/库:

// jso1 and jso2 are some JSONObjects already instantiated
JSONObject Obj1 = (JSONObject) jso.get("Object1");
JSONObject Obj2 = (JSONObject) jso.get("Object2");
Run Code Online (Sandbox Code Playgroud)

所以在这种情况下,我想结合Obj1Obj2,要么做一个全新的JSONObject或CONCAT一个到另一个.除了将它们分开并单独添加puts 之外的任何想法?

Mat*_*hen 53

如果你想要一个带有两个键Object1和Object2的新对象,你可以这样做:

JSONObject Obj1 = (JSONObject) jso1.get("Object1");
JSONObject Obj2 = (JSONObject) jso2.get("Object2");
JSONObject combined = new JSONObject();
combined.put("Object1", Obj1);
combined.put("Object2", Obj2);
Run Code Online (Sandbox Code Playgroud)

如果你想合并它们,那么例如顶级对象有5个键(Stringkey1,ArrayKey,StringKey2,StringKey3,StringKey4),我想你必须手动完成:

JSONObject merged = new JSONObject(Obj1, JSONObject.getNames(Obj1));
for(String key : JSONObject.getNames(Obj2))
{
  merged.put(key, Obj2.get(key));
}
Run Code Online (Sandbox Code Playgroud)

如果JSONObject实现了Map,并且支持putAll,这将会容易得多.

  • 我正在尝试在 Android 中使用您的第二个代码片段,但我没有在 JSONObject 上看到静态 getNames 函数。这是在 org.json 库的较新版本中添加的吗? (2认同)
  • @AustynMahoney,不确定历史,但对于Android,你可以使用实例方法[`JSONObject.names`](http://developer.android.com/reference/org/json/JSONObject.html#names%28% 29). (2认同)
  • 如果 jsonobject 为空,JSONObject.getNames() 方法将返回 null。您还需要检查这种情况。 (2认同)

San*_* P. 20

您可以像这样创建一个新的JSONObject:

JSONObject merged = new JSONObject();
JSONObject[] objs = new JSONObject[] { Obj1, Obj2 };
for (JSONObject obj : objs) {
    Iterator it = obj.keys();
    while (it.hasNext()) {
        String key = (String)it.next();
        merged.put(key, obj.get(key));
    }
}
Run Code Online (Sandbox Code Playgroud)

使用此代码,如果您之间有任何重复的键Obj1,Obj2则值Obj2将保留.如果希望Obj1保留值in ,则应该反转第2行中数组的顺序.


Ere*_*evi 19

在某些情况下,您需要深度合并,即合并具有相同名称的字段的内容(就像在Windows中复制文件夹时一样).此功能可能会有所帮助:

/**
 * Merge "source" into "target". If fields have equal name, merge them recursively.
 * @return the merged object (target).
 */
public static JSONObject deepMerge(JSONObject source, JSONObject target) throws JSONException {
    for (String key: JSONObject.getNames(source)) {
            Object value = source.get(key);
            if (!target.has(key)) {
                // new value for "key":
                target.put(key, value);
            } else {
                // existing value for "key" - recursively deep merge:
                if (value instanceof JSONObject) {
                    JSONObject valueJson = (JSONObject)value;
                    deepMerge(valueJson, target.getJSONObject(key));
                } else {
                    target.put(key, value);
                }
            }
    }
    return target;
}



/**
 * demo program
 */
public static void main(String[] args) throws JSONException {
    JSONObject a = new JSONObject("{offer: {issue1: value1}, accept: true}");
    JSONObject b = new JSONObject("{offer: {issue2: value2}, reject: false}");
    System.out.println(a+ " + " + b+" = "+JsonUtils.deepMerge(a,b));
    // prints:
    // {"accept":true,"offer":{"issue1":"value1"}} + {"reject":false,"offer":{"issue2":"value2"}} = {"reject":false,"accept":true,"offer":{"issue1":"value1","issue2":"value2"}}
}
Run Code Online (Sandbox Code Playgroud)

  • 如果“source”中的值是 JSONArray 类型怎么办?在这种情况下,我们需要将此数组与目标对象的等效 JSONArray 合并。 (2认同)

Dav*_*jan 6

这种包装方法将有助于:

private static JSONObject merge(JSONObject... jsonObjects) throws JSONException {

    JSONObject jsonObject = new JSONObject();

    for(JSONObject temp : jsonObjects){
        Iterator<String> keys = temp.keys();
        while(keys.hasNext()){
            String key = keys.next();
            jsonObject.put(key, temp.get(key));
        }

    }
    return jsonObject;
}
Run Code Online (Sandbox Code Playgroud)