diff --git a/json-modules/json-2/pom.xml b/json-modules/json-2/pom.xml index ecffd719c7..ee58ab8b25 100644 --- a/json-modules/json-2/pom.xml +++ b/json-modules/json-2/pom.xml @@ -108,6 +108,17 @@ + + commons-io + commons-io + 2.11.0 + + + org.junit.jupiter + junit-jupiter + RELEASE + test + diff --git a/json-modules/json-2/src/main/java/com/baeldung/jsonvaluegetter/JSONObjectValueGetter.java b/json-modules/json-2/src/main/java/com/baeldung/jsonvaluegetter/JSONObjectValueGetter.java new file mode 100644 index 0000000000..f8d38106fd --- /dev/null +++ b/json-modules/json-2/src/main/java/com/baeldung/jsonvaluegetter/JSONObjectValueGetter.java @@ -0,0 +1,87 @@ +package com.baeldung.jsonvaluegetter; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +public class JSONObjectValueGetter { + + /** + * Get values associated with the provided key in the given JSONObject instance + * + * @param jsonObject JSONObject instance in which to search the key + * @param key Key we're interested in + * + * @return List of values associated with the given key, in the order of appearance. + * If the key is absent, empty list is returned. + */ + public List getValuesInObject(JSONObject jsonObject, String key) { + List accumulatedValues = new ArrayList<>(); + for (String currentKey : jsonObject.keySet()) { + Object value = jsonObject.get(currentKey); + if (currentKey.equals(key)) { + accumulatedValues.add(value.toString()); + } + + if (value instanceof JSONObject) { + accumulatedValues.addAll(getValuesInObject((JSONObject)value, key)); + } else if (value instanceof JSONArray) { + accumulatedValues.addAll(getValuesInArray((JSONArray)value, key)); + } + } + + return accumulatedValues; + } + + /** + * Get values associated with the provided key in the given JSONArray instance + * + * @param jsonArray JSONArray instance in which to search the key + * @param key Key we're interested in + * + * @return List of values associated with the given key, in the order of appearance. + * If the key is absent, empty list is returned. + */ + public List getValuesInArray(JSONArray jsonArray, String key) { + List accumulatedValues = new ArrayList<>(); + for (Object obj : jsonArray) { + if (obj instanceof JSONArray) { + accumulatedValues.addAll(getValuesInArray((JSONArray)obj, key)); + } else if (obj instanceof JSONObject) { + accumulatedValues.addAll(getValuesInObject((JSONObject)obj, key)); + } + } + + return accumulatedValues; + } + + /** + * Among all the values associated with the given key, get the N-th value + * + * @param jsonObject JSONObject instance in which to search the key + * @param key Key we're interested in + * @param N Index of the value to get + * + * @return N-th value associated with the key, or null if the key is absent or + * the number of values associated with the key is less than N + */ + public String getNthValue(JSONObject jsonObject, String key, int N) { + List values = getValuesInObject(jsonObject, key); + return (values.size() >= N) ? values.get(N - 1) : null; + } + + /** + * Count the number of values associated with the given key + * + * @param jsonObject JSONObject instance in which to count the key + * @param key Key we're interested in + * + * @return The number of values associated with the given key + */ + public int getCount(JSONObject jsonObject, String key) { + List values = getValuesInObject(jsonObject, key); + return values.size(); + } +} diff --git a/json-modules/json-2/src/test/java/com/baeldung/jsonvaluegetter/JSONObjectValueGetterUnitTest.java b/json-modules/json-2/src/test/java/com/baeldung/jsonvaluegetter/JSONObjectValueGetterUnitTest.java new file mode 100644 index 0000000000..fc17e700eb --- /dev/null +++ b/json-modules/json-2/src/test/java/com/baeldung/jsonvaluegetter/JSONObjectValueGetterUnitTest.java @@ -0,0 +1,69 @@ +package com.baeldung.jsonvaluegetter; + +import org.apache.commons.io.IOUtils; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +public class JSONObjectValueGetterUnitTest { + + private static JSONObject jsonObject; + private static JSONObjectValueGetter jsonObjectValueGetter = new JSONObjectValueGetter(); + + @BeforeAll + public static void loadJsonContent() throws IOException { + InputStream inputStream = JSONObjectValueGetterUnitTest.class.getClassLoader().getResourceAsStream("employee.json"); + String jsonString = IOUtils.toString(inputStream, "UTF-8"); + jsonObject = new JSONObject(jsonString); + } + + @Test + public void getValueDirectly() { + JSONArray family = jsonObject.getJSONArray("family"); + JSONObject sonObject = family.getJSONObject(1); + JSONObject sonData = sonObject.getJSONObject("son"); + String sonName = sonData.getString("name"); + Assertions.assertEquals(sonName, "Peter"); + } + + @Test + public void getAllAssociatedValuesRecursively() { + List values = jsonObjectValueGetter.getValuesInObject(jsonObject, "son"); + Assertions.assertEquals(values.size(), 1); + + String sonString = values.get(0); + Assertions.assertTrue(sonString.contains("Peter")); + Assertions.assertTrue(sonString.contains("Schoolboy")); + Assertions.assertTrue(sonString.contains("11")); + + values = jsonObjectValueGetter.getValuesInObject(jsonObject, "name"); + Assertions.assertEquals(values.size(), 3); + + Assertions.assertEquals(values.get(0), "Bob"); + Assertions.assertEquals(values.get(1), "Alice"); + Assertions.assertEquals(values.get(2), "Peter"); + } + + @Test + public void getNthValueRecursively() { + Assertions.assertEquals(jsonObjectValueGetter.getNthValue(jsonObject, "name", 1), "Bob"); + Assertions.assertEquals(jsonObjectValueGetter.getNthValue(jsonObject, "name", 2), "Alice"); + Assertions.assertEquals(jsonObjectValueGetter.getNthValue(jsonObject, "name", 3), "Peter"); + Assertions.assertNull(jsonObjectValueGetter.getNthValue(jsonObject, "nonExistingKey", 1)); + } + + @Test + public void getCountRecursively() { + Assertions.assertEquals(jsonObjectValueGetter.getCount(jsonObject, "name"), 3); + Assertions.assertEquals(jsonObjectValueGetter.getCount(jsonObject, "age"), 3); + Assertions.assertEquals(jsonObjectValueGetter.getCount(jsonObject, "occupation"), 1); + Assertions.assertEquals(jsonObjectValueGetter.getCount(jsonObject, "nonExistingKey"), 0); + } +} diff --git a/json-modules/json-2/src/test/resources/employee.json b/json-modules/json-2/src/test/resources/employee.json new file mode 100644 index 0000000000..095190212a --- /dev/null +++ b/json-modules/json-2/src/test/resources/employee.json @@ -0,0 +1,30 @@ +{ + "name" : "Bob", + "profession" : "Software engineer", + "department" : "Research", + "age" : 40, + "family" : [ + { + "wife" : { + "name" : "Alice", + "profession" : "Doctor", + "age" : 38 + } + }, + { + "son" : { + "name" : "Peter", + "occupation" : "Schoolboy", + "age" : 11 + } + } + ], + "performance" : [ + { + "2020" : 4.5 + }, + { + "2021" : 4.8 + } + ] +} \ No newline at end of file