【问题标题】:Java 8: How to write lambda stream to work with JsonArray?Java 8:如何编写 lambda 流以使用 JsonArray?
【发布时间】:2017-06-16 18:04:13
【问题描述】:

我对 Java 8 lambda 和其他东西非常陌生...我想编写一个 lambda 函数,它接受 JSONArray,遍历其 JSONObjects 并创建某个字段的值列表。

例如,一个函数接受JSONArray: [{name: "John"}, {name: "David"}] 并返回["John", "David"] 的列表。

我写了以下代码:

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);
    }
}

但是,我收到一个错误:

线程“主”java.lang.NullPointerException 中的异常

你知道怎么解决吗?

【问题讨论】:

  • put() 按该名称返回以前的 value ,在您的情况下意味着 nullput() 不是 chaining method

标签: java lambda java-8 java-stream


【解决方案1】:

尝试使用 IntStream。

List<String> jsonObject = IntStream
       .range(0,jsonArray.size())
       .mapToObj(i -> jsonArray.getJSONObject(i))
       .collect(Collectors.toList());

【讨论】:

  • 方法 getJSONObject 抛出 JSONException,因此代码的 3d 行无效,因为它应该包含一个 try-catch 块。
  • 我使用了这个解决方案并且工作正常。 @George siggouroglou 您可以重新检查一下。您的评论具有误导性,即使它throws,您也要编写throwing function。 AFAIK,我喜欢这个答案。
【解决方案2】:

JSONArrayjava.util.ArrayList 的子类,JSONObjectjava.util.HashMap 的子类。

因此,new JSONObject().put("name", "John") 返回与键关联的先前值 (null),而不是 JSONObject 实例。结果,null 被添加到JSONArray

另一方面,这有效:

    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);

出于某种原因,我不得不将流管道分成两个步骤,否则编译器无法识别 .collect (Collectors.toList()) 返回 List

输出是:

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

【讨论】:

  • 原始ArrayListHashMapstream() 管道未编译的原因。
  • 我认为它与JSONArray 扩展原始ArrayList 有关,但我认为在.map (json-&gt;json.toString ()) 之后编译器可以意识到结果必须是Stream&lt;String&gt;,不管原始原始Stream中的元素类型。
  • 我猜它可以,但map 会立即从其对原始Stream 的调用中删除。
  • 这不适用于 org.json.jsonarray 类型,除非您专门从 json-simple jsonarray 进行转换。
【解决方案3】:

是的,我认识到 put 的结果被添加到 json 数组而不是 json 对象中。应该是这样的。

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);
}

现在的输出是 [{"name":"John"}, {"name":"David"}] 符合预期

【讨论】:

    猜你喜欢
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    • 2018-06-02
    • 2019-06-04
    • 1970-01-01
    • 1970-01-01
    • 2014-07-13
    • 2014-04-16
    相关资源
    最近更新 更多