0

I have two JSON strings which are essentially arrays of JSONObject. The two JSON strings have below structure and keys:

JSON-1:

[
    {
        "title": "ABC",
        "edition": 7,
        "year": 2011
    },
    {
        "title": "DEF",
        "edition": 2,
        "year": 2012
    },
    {
        "title": "XYZ",
        "edition": 3,
        "year": 2013
    }
]

And, JSON-2:

[
    {
        "title": "ABC",
        "price": "20"
    },
    {
        "title": "DEF",
        "price": "20"
    },
    {
        "title": "XYZ",
        "price": "20"
    }
]

Both these JSONs have a common key "title" based on which I want to merge these two JSONs, either merging JSON-2 values into JSON-1 or creating a JSON object with the merged result.

The merged result should look like below:

[
    {
        "title": "ABC",
        "edition": 7,
        "year": 2011,
        "price": "20"
    },
    {
        "title": "DEF",
        "edition": 2,
        "year": 2012
        "price": "20"
    },
    {
        "title": "XYZ",
        "edition": 3,
        "year": 2013
        "price": "20"
    }
]

How can I achieve this by minimum looping and minimum object creation? I also can not use entity/model classes. The idea is to do it without creating any model classes.

Note: I cannot use Gson because I don't have the approval to use the same.

  1. I tried to use List<JSONObject> listObj = objectMapper.readValue(jsonOneString, new TypeReference<List<JSONObject>>(){});, but I am getting an unknown property exception.

  2. I tried JsonNode node = objectMapper.readTree(jsonOneString);, but I cannot proceed much further with this approach.

I know what I am doing here is highly inefficient, so looking for ways which will use no entity class, minimum new object creation and minimum loops. Kindly advise.

UPDATE: I updated the below code with a slight modification:

if (json1elem.get("title")!=null 
        && json2elem.get("title")!=null 
            && json1elem.get("title").equals(json2elem.get("title"))) {

    //
}
2
  • You "cannot use third-party libraries", yet you're already using a third-party library called Jackson. Commented Sep 8, 2022 at 17:32
  • I see what mistake I did there. What I meant by that is, Even though this problem is easily solved with Gson library, currently can't include it in our pom as it needs a lot of approvals. Hence that statement Commented Sep 9, 2022 at 1:13

2 Answers 2

0
JsonNode json1 = objectMapper.readTree(jsonOneString);
JsonNode json2 = objectMapper.readTree(jsonTwoString);
for (JsonNode json1elem : json1) {
    for (JsonNode json2elem : json2) {
        if (json1elem.get("title").equals(json2elem.get("title"))) {
            ((ObjectNode) json1elem).setAll((ObjectNode) json2elem);
            break;
        }
    }
}
System.out.println(json1.toPrettyString());
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Raymond. I'll try this out today. Meanwhile could you please help me to understand why is this not working for me: List<JSONObject> listObj = objectMapper.readValue(jsonOneString, new TypeReference<List<JSONObject>>(){}); Is there a way to convert jsonOneString into a List<JSONObject> ?
Please check my UPDATE at the bottom of the question.
You may refer to this. I haven't verify it.
0
public static JSONObject deepMerge(JSONObject source, JSONObject target) throws JSONException {
        Iterator it = source.keys();
        while (it.hasNext()) {
            String key = (String) it.next();
            Object value = source.get(key);
            if (!target.has(key)) {
                target.put(key, value);
            } else {
                if (value instanceof JSONArray) {
                    JSONArray valueArry = (JSONArray) value;
                    for (int i = 0; i < valueArry.length(); i++) {
                        if (valueArry.get(i) instanceof JSONObject) {
                            JSONObject jsonObj = (JSONObject) valueArry.get(i);
                            JSONObject valueJson1 = (JSONObject) jsonObj;
                            JSONArray targetArray = target.getJSONArray(key);
                            deepMerge(valueJson1, targetArray.getJSONObject(i));
                        }
                    }
                } else if (value instanceof JSONObject) {
                    JSONObject valueJson = (JSONObject) value;
                    deepMerge(valueJson, target.getJSONObject(key));
                } else {
                    target.put(key, value);
                }
            }
        }
        return target;
    }

2 Comments

I assume that the parameters to method deepMerge are created from the sample JSON strings in the posted question. Maybe you can edit your answer and add code showing how to create the method parameters from the JSON strings?
Give a high-level explanation of what you need to do first and then go into code.

Your Answer

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.