我有一个双精度数组,我需要使用 java
JSONArray
将数组转换为 streams
。我尝试使用 forEach (共享可变性),这会导致数据丢失。
public static JSONArray arrayToJson(double[] array) throws JSONException{
JSONArray jsonArray = new JSONArray();
Arrays.stream(array)
.forEach(jsonArray::put);
return jsonArray;
}
有什么方法可以使用流来创建
JSONArray
吗?
你的代码可以工作,但你可以写这样的东西(
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
));
再一个示例(从
String
创建 List<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.1
和JSON 20190722
上检查了这一点,除了Expected 3 arguments, but found 1
中的.collect(...)
之外没有发现问题。
(摇篮:
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
的方法引用,因为这只会将一个数组放入另一个数组中(例如 [[]]
),而不是按照所需的行为实际组合它们。
JSONArray
不是线程安全的。如果您使用并行流,您应该同步操作。
Arrays
.stream(array)
.parallel()
.forEach(e -> {
synchronized(jsonArray) {
jsonArray.put(e);
}
});