In Java, how can I combine two JSON arrays of objects?
You really have only two choices: parse the JSON (which invariably would involve constructing the objects) or don't parse the JSON. Not parsing is going to be cheaper, of course.
At first glance your idea about treating it as a String-manipulation problem might sound fragile, but the more I think about it, the more it seems to make fine sense. For error detection you could easily confirm that you were really dealing with arrays by checking for the square brackets; after that, just stripping off the ending bracket, adding a comma, stripping off the beginning bracket, and adding the "tail" should work flawlessly. The only exception I can think of is if either array is empty, you should just return the other String unchanged; again, that's very easy to check for as a String.
I really don't think there's any reason to make it more complex than that.
how to merge json array using java?
Try below code, This will give your desired result.
JSONArray jsonArray = new JSONArray();
JSONArray jsonArray1 = new JSONArray();
try {
for (int i = 0; i < jsonArray1.length(); i++) {
JSONObject jsonObject = jsonArray1.getJSONObject(i);
jsonArray.put(jsonObject);
}
} catch (JSONException e) {
e.printStackTrace();
}
Now use jsonArray
which is having all merged jsonObject
Merge values of two JSON Array into a JSONObject java
Let's combine both array using RxJava
JSONArray combinedArray = new JSONArray();
List<Integer> idList = Arrays.asList(6, 7, 8, 9, 10, 11);
List<Integer> timestampList = Arrays.asList(122402538, 12240345, 122496, 122617, 1227473, 1228495);
final int[] counter = {0}; // assuming your both array are of same size.
Observable.fromIterable(idList)
.map(id -> {
JSONObject singleObject = new JSONObject();
singleObject.put("id:", id);
singleObject.put("timestamp:", timestampList.get(counter[0]));
counter[0]++;
combinedArray.put(singleObject);
return Observable.just(combinedArray);
}
)
.toList() //jsonArrayObservable is observable json array, if you want to your later on
.doOnSuccess(jsonArrayObservable -> Log.d("jsonArrayObservable -> ", combinedArray.toString()))
.subscribe();
OUTPUT
jsonArrayObservable -> :[{"id:":6,"timestamp:":122402538},{"id:":7,"timestamp:":12240345},{"id:":8,"timestamp:":122496},{"id:":9,"timestamp:":122617},{"id:":10,"timestamp:":1227473},{"id:":11,"timestamp:":1228495}]
UPDATE without support of java 8
Observable.fromIterable(idList)
.map(new Function<Integer, Object>() {
@Override
public Object apply(Integer id) throws Exception {
JSONObject singleObject = new JSONObject();
singleObject.put("id:", id);
singleObject.put("timestamp:", timestampList.get(counter[0]));
counter[0]++;
combinedArray.put(singleObject);
return Observable.just(combinedArray);
}
}
)
.toList() //jsonArrayObservable is observable json array, if you want to your later on
.doOnSuccess(jsonArrayObservable -> Log.d("jsonArrayObservable -> ", combinedArray.toString()))
.subscribe();
Output
Merge two JSONs to JSONObject instead of JSONArray
I prefer and recommend use Gson from Google:
The last release is 2.8.6 from Oct of 2019:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
Always check last version on Maven Central Repository:
- https://mvnrepository.com/artifact/com.google.code.gson/gson
Example:
public static void mergeJSONs() {
String JSON1 = "{\"1level1\":{\"1level2\":{\"1label1\":\"1value1\"}}}";
String JSON2 = "{\"1level1\":{\"1level2\":{\"1label2\":\"1value2\"}}}";
String JSON3 = "{\"2level1\":{\"2level2\":{\"2level3\":{\"2label1\":\"2value1\"}}}}";
String JSON4 = "{\"2level1\":{\"2level2\":{\"2label2\":\"2value2\"}}}";
String finalJson = organizeJson(JSON1, JSON2, JSON3, JSON4);
System.out.println(finalJson);
}
The method can receive a list of json payloads, add a root element and merge:
public String organizeJson(String... jsonList) throws Exception {
JsonObject jsonObj = null;
Gson gson = new GsonBuilder().setPrettyPrinting().create();
for (String json : jsonList) {
if (jsonObj != null) {
jsonObj = jsonMerge(jsonObj, gson.fromJson(json, JsonObject.class));
} else {
jsonObj = gson.fromJson(json, JsonObject.class);
}
}
JsonObject jsonStringsRoot = new JsonObject();
/* Add "strings" as root element */
jsonStringsRoot.add("strings", jsonObj);
return gson.toJson(jsonStringsRoot);
}
Method using recursive call to find the last level on nested objects (deep merge):
public static JsonObject jsonMerge(JsonObject jsonA, JsonObject jsonB) throws Exception {
for (Map.Entry<String, JsonElement> sourceEntry : jsonA.entrySet()) {
String key = sourceEntry.getKey();
JsonElement value = sourceEntry.getValue();
if (!jsonB.has(key)) {
if (!value.isJsonNull()) {
jsonB.add(key, value);
}
} else {
if (!value.isJsonNull()) {
if (value.isJsonObject()) {
jsonMerge(value.getAsJsonObject(), jsonB.get(key).getAsJsonObject());
} else {
jsonB.add(key, value);
}
} else {
jsonB.remove(key);
}
}
}
return jsonB;
}
Reference:
- https://stackoverflow.com/a/38757661/5626568
Recursively merging two JSON objects with different levels same key
I would say your .map()
attempt is going into the right direction, and also your hunch that you need recursion. What works is
function mergeById(r1, r2) {
return r1.map(({item_guid, sub_items, ...rest}) => Object.assign(
rest,
{item_guid},
r2.find(_ => _.item_guid === item_guid),
{sub_items: mergeById(sub_items, r2)}
));
}
const r1 = [{item_guid: "5c2000c1-abc8-4d6f-85de-b8b223a42a2f", item_id: 1, parent_item_id: null, description: "1", sub_items: [{item_guid: "bd7c2ba3-268b-49f6-98fb-34486a3e1449", item_id: 10, parent_item_id: 1, description: "1.1", sub_items: []}, {item_guid: "80e073e0-2aa8-422a-9f28-51747f146bd8", item_id: 12, parent_item_id: 1, description: "1.2", sub_items: [{item_guid: "f97af55c-c90e-46c2-b56e-e854ff36e1e3", item_id: 78, parent_item_id: 12, description: "1.2.1", sub_items: []}, {item_guid: "28469fa4-2c1c-4f2a-9250-7460a74cc30a", item_id: 79, parent_item_id: 12, description: "1.2.2", sub_items: [{item_guid: "f97af55c-c90e-46c2-b56e-e854ff36e1e9", item_id: 80, parent_item_id: 12, description: "1.2.2.1", sub_items: []}]}]}, {item_guid: "846daeab-edd4-4cf2-8f12-8d7231c697e3", item_id: 13, parent_item_id: 1, description: "1.3", sub_items: []}]}]
const r2 = [{item_guid: "bd7c2ba3-268b-49f6-98fb-34486a3e1449", mandatory: "True", comment: "Item cross-reference 1.1"}, {item_guid: "f97af55c-c90e-46c2-b56e-e854ff36e1e3", mandatory: "True", comment: "Item cross-reference 1.2.1"}, {item_guid: "f97af55c-c90e-46c2-b56e-e854ff36e1e9", mandatory: "True", comment: "Item cross-reference 1.2.2.1"}]
console.log(mergeById(r1, r2))
.as-console-wrapper {max-height: 100% !important; top: 0}
Related Topics
Javax.Net.Ssl.Sslexception: Certificate Doesn't Match Any of the Subject Alternative Names
How to Pass Bundle With Arraylist from Fragment to Activity
Error: Could Not Find or Load Main Class in Intellij Ide
Deserialization With @Jsonsubtypes for No Value - Missing Property Error
Crudrepository and Hibernate: Save(List<S>) VS Save(Entity) in Transaction
How to Get Row Count Using Resultset in Java
Hibernate Foreign Key Issue:Error Executing Ddl "Alter Table..."
Source Folder Is Not on the Java Build Class Path, Creating Java Package
How to Shut Down a Spring Boot Command-Line Application
Converting Number Representing a Date in Excel to a Java Date Object
Java H2 In-Memory Database Error: Table Not Found
Method Does Not Override Method from Its Superclass . Android Fragment
How to Get Full Name of an Employee by Joining First, Middle and Last Name Considering Null in Java
Regular Expression to Match a Backslash Followed by a Quote
Select the Letters After - in a String
Way to Check If Two Collections Contain the Same Elements, Independent of Order