DEV Community

Cover image for How to find value using path array on structural document in Java
Kooin-Shin
Kooin-Shin

Posted on • Edited on

How to find value using path array on structural document in Java

Sometimes we need to find a value on structural document like JSON, YAML. Also there is sometime to need to find a value by path of document.

Structural document can be easily converted to Map-List object with parser libraries. Because of it, we can get a value of the document using key and index array.

To do that,

First, we need to get a parser library that can parse JSON or YAML to Java Map-List structure. That library can be found easily in internet library repository like Maven Central.

For this post, we assume that we target JSON document.
It's down below

{
  "id": "0001",
  "type": "donut",
  "name": "Cake",
  "ppu": 0.55,
  "batters": {
    "aaa": {
      "bbb": {
        "ccc": {
          "value": 123.0
        }
      }
    },
    "batter": [
      {
        "id": "1001",
        "type": "Regular"
      },
      {
        "id": "1002",
        "type": "Chocolate"
      },
      {
        "id": "1003",
        "type": "Blueberry"
      },
      {
        "id": "1004",
        "type": "Devil\u0027s Food"
      }
    ]
  },
Enter fullscreen mode Exit fullscreen mode

We use recursive algorithm to find a value and if path can't find value or path isn't exist, It will return null.

Completed code is down below

    /**
     * To find value with path array on structural data
     * 
     * @param obj
     * @param keys
     * @return
     */
    public static Object findValue(Object obj, Object[] keys) {
        if (obj instanceof List) {
            List list = (List) obj;
            if (keys.length == 1) {
                if (keys[0] instanceof Integer && list.size() > (int) keys[0]) {
                    return list.get((int) keys[0]);
                }
            } else if (keys.length > 1 && list.size() > 0) {
                int idx = (int)keys[0];
                if(idx < list.size()) {
                    return findValue(list.get((int) keys[0]), Arrays.copyOfRange(keys, 1, keys.length));
                }
            }
        } else if (obj instanceof Map) {
            Map map = (Map) obj;
            if (keys.length == 1 && map.containsKey(keys[0])) {
                return map.get(keys[0]);
            } else if (keys.length > 1 && map.containsKey(keys[0])) {
                if(keys.length > 0) {
                    return findValue(map.get(keys[0]), Arrays.copyOfRange(keys, 1, keys.length));
                }
            }
        }
        return null;
    }
Enter fullscreen mode Exit fullscreen mode

Well, let's start test now

Above JSON document save to file named 'sample.json'
Below code is read 'sample.json' and result is image more below.

Gson gson = new Gson();
Map<String, Object> map = gson.fromJson(new FileReader("simple.json"), Map.class);
Object[] keys = new Object[] {"batters", "batter", 3, "type"};

Object obj = findValue(map, keys);
System.out.println(obj);
Enter fullscreen mode Exit fullscreen mode

Alt Text

Top comments (0)