Merge (Concat) Multiple JSONObjects in Java

If you want a new object with two keys, Object1 and Object2, you can do:

JSONObject Obj1 = (JSONObject) jso1.get("Object1");
JSONObject Obj2 = (JSONObject) jso2.get("Object2");
JSONObject combined = new JSONObject();
combined.put("Object1", Obj1);
combined.put("Object2", Obj2);

If you want to merge them, so e.g. a top level object has 5 keys (Stringkey1, ArrayKey, StringKey2, StringKey3, StringKey4), I think you have to do that manually:

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

This would be a lot easier if JSONObject implemented Map, and supported putAll.


In some cases you need a deep merge, i.e., merge the contents of fields with identical names (just like when copying folders in Windows). This function may be helpful:

/**
 * 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"}}
}

You can create a new JSONObject like this:

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

With this code, if you have any repeated keys between Obj1 and Obj2 the value in Obj2 will remain. If you want the values in Obj1 to be kept you should invert the order of the array in line 2.


This wrapper method will help :

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