【发布时间】:2020-01-05 21:38:33
【问题描述】:
在 Stream 上调用“reduce”时,我观察到对基础集合的副作用。这是非常基本的。我不敢相信我所看到的,但我找不到错误。下面是代码和结果输出。谁能向我解释为什么 Stream 的底层集合之一发生了变异?
package top;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) throws Exception {
ArrayList<Integer> list1 = new ArrayList<>();
ArrayList<Integer> list2 = new ArrayList<>();
ArrayList<Integer> list3 = new ArrayList<>();
list1.addAll(Arrays.asList(1, 2, 3));
list2.addAll(Arrays.asList(4, 5, 6));
list3.addAll(Arrays.asList(7, 8, 9));
System.out.println("Before");
System.out.println(list1);
System.out.println(list2);
System.out.println(list3);
ArrayList<Integer> r1 = Stream.of(list1, list2, list3).reduce((l, r) -> {
l.addAll(r);
return l;
}).orElse(new ArrayList<>());
System.out.println("After");
System.out.println(list1);
System.out.println(list2);
System.out.println(list3);
System.out.println("Result");
System.out.println(r1);
}
}
// Output
Before
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
After
[1, 2, 3, 4, 5, 6, 7, 8, 9] // Why is this not [1,2,3]?
[4, 5, 6]
[7, 8, 9]
Result
[1, 2, 3, 4, 5, 6, 7, 8, 9]
【问题讨论】:
-
废话。我想我意识到这正是它在 Java 中的工作方式。那正确吗?真的吗?
-
你认为
l.addAll(r)是做什么的?它更新l列表的内容。那么,为什么您对列表已更新感到困惑? -
是的,您明确告诉您的代码这样做:使用
l.addAll(r); return l;您告诉将所有内容添加到左侧列表,然后返回左侧列表。对于每次迭代,左侧列表为list1。好吧,我认为布赖恩的回答已经足够解释了。
标签: java java-8 java-stream side-effects