【问题标题】:How to convert a collection/ array into JSONArray using stream in java 8如何使用 java 8 中的流将集合/数组转换为 JSONArray
【发布时间】:2018-06-17 03:30:39
【问题描述】:

我有一个双数组,我需要使用 java streams 将数组转换为 JSONArray。我尝试使用导致数据丢失的 forEach(共享可变性)。

public static JSONArray arrayToJson(double[] array) throws JSONException{
    JSONArray jsonArray = new JSONArray();
    
    Arrays.stream(array)
         .forEach(jsonArray::put);  

    return jsonArray;
}

有什么方法可以使用流创建JSONArray

【问题讨论】:

  • “数据丢失”是什么意思?
  • 您的代码运行良好,没有数据丢失。
  • 你使用的是什么 JSon 库!
  • 为什么使用并行流,目的是什么?请编辑您的问题并添加此信息,这可能会有所不同。
  • JSONArray 不是线程安全的,您可以查看文档。

标签: java arrays java-8 stream java-stream


【解决方案1】:

您的代码有效,但您可以编写如下内容 (jdk 8+):

return Arrays.stream(array)
             .collect(Collector.of(
                          JSONArray::new, //init accumulator
                          JSONArray::put, //processing each element
                          JSONArray::put  //confluence 2 accumulators in parallel execution
                     ));

另一个例子(从List<String>创建一个String

List<String> list = ...
String str = list.stream()
                 .collect(Collector.of(
                    StringBuilder::new,
                    StringBuilder::append,
                    StringBuilder::append,
                    StringBuilder::toString //last action of the accumulator (optional)  
                 ));

看起来不错,但编译器抱怨:error: incompatible thrown types JSONException in method reference .collect(Collector.of(JSONArray::new, JSONArray::put, JSONArray::put)

我在jdk 13.0.1JSON 20190722 上检查了这个问题,除了.collect(...) 中的Expected 3 arguments, but found 1 之外没有发现问题。

(Gradle : implementation group: 'org.json', name: 'json', version: '20190722')


修复:

public static JSONArray arrayToJson(double[] array) throws JSONException {
    return Arrays.stream(array).collect(
            JSONArray::new,
            JSONArray::put,
            (ja1, ja2) -> {
                for (final Object o : ja2) {
                    ja1.put(o);
                }
            }
    );
}

注意:组合器不能只是对JSONArray::put 的方法引用,因为这只会将一个数组放入另一个数组(例如[[]]),而不是按照期望的行为实际组合它们.

【讨论】:

  • 看起来不错,但编译器抱怨:错误:方法引用中抛出的 JSONException 类型不兼容 .collect(Collector.of(JSONArray::new, JSONArray::put, JSONArray::put))
【解决方案2】:

JSONArray 不是线程安全的。如果你使用并行流,你应该同步操作。

Arrays
    .stream(array)
    .parallel()
    .forEach(e -> {
        synchronized(jsonArray) {
            jsonArray.put(e);
        }
    });

【讨论】:

  • 如果你同步操作,你不需要使用并行,因为你没有任何优势。
猜你喜欢
  • 2014-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-05
  • 2015-07-31
  • 1970-01-01
相关资源
最近更新 更多