Search code examples
javalambdajava-8java-stream

Java 8: How to write lambda stream to work with JSONArray?


I'm very new to Java 8 lambdas and stuff. I want to write a lambda function that takes a JSONArray, goes over its JSONObjects and creates a list of values of certain field.

For example, a function that takes the JSONArray

[{name: "John"}, {name: "David"}]

and returns a list of ["John", "David"].

I wrote the following code:

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

public class Main {

    public static void main(String[] args) {
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(new JSONObject().put("name", "John"));
        jsonArray.add(new JSONObject().put("name", "David"));
        List list = (List) jsonArray.stream().map(json -> json.toString()).collect(Collectors.toList());
        System.out.println(list);
    }

}

However, I get an error:

Exception in thread "main" java.lang.NullPointerException

Do you know how to resolve it?


Solution

  • JSONArray is a sub-class of java.util.ArrayList and JSONObject is a sub-class of java.util.HashMap.

    Therefore, new JSONObject().put("name", "John") returns the previous value associated with the key (null), not the JSONObject instance. As a result, null is added to the JSONArray.

    This, on the other hand, works:

        JSONArray jsonArray = new JSONArray();
        JSONObject j1 = new JSONObject();
        j1.put ("name", "John");
        JSONObject j2 = new JSONObject();
        j2.put ("name", "David");
        jsonArray.add(j1);
        jsonArray.add(j2);
        Stream<String> ss = jsonArray.stream().map (json->json.toString ());
        List<String> list = ss.collect (Collectors.toList ());
        System.out.println(list);
    

    For some reason I had to split the stream pipeline into two steps, because otherwise the compiler doesn't recognize that .collect (Collectors.toList()) returns a List.

    The output is:

    [{"name":"John"}, {"name":"David"}]