Java 8: How to write lambda stream to work with Js

2020-02-11 05:17发布

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?

3条回答
倾城 Initia
2楼-- · 2020-02-11 05:57

Yes, I recognized that result of put is being added to json array instead of json object. Should be like this.

private static JSONObject getJson(String key, String value){
    JSONObject result = new JSONObject();
    result.put(key, value);
    return result;        
}

public static void main(String[] args) {
    JSONArray jsonArray = new JSONArray();

    jsonArray.add(getJson("name", "John"));
    jsonArray.add(getJson("name", "David"));

    List list = (List) jsonArray.stream()
                .map(json -> json.toString())
                .collect(Collectors.toList());
    System.out.println(list);
}

and output is now [{"name":"John"}, {"name":"David"}] like expected

查看更多
三岁会撩人
3楼-- · 2020-02-11 06:08

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"}]
查看更多
Juvenile、少年°
4楼-- · 2020-02-11 06:15

Try with IntStream.

List<String> jsonObject = IntStream
       .range(0,jsonArray.size())
       .mapToObj(i -> jsonArray.getJSONObject(i))
       .collect(Collectors.toList());
查看更多
登录 后发表回答