【发布时间】:2017-10-28 10:18:33
【问题描述】:
我正在观看有关 Java 的演示文稿,有一次,讲师说:
“可变性是好的,共享是好的,共享可变性是魔鬼的工作。”
他指的是下面这段代码,他认为这是一个“非常坏的习惯”:
//double the even values and put that into a list.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 1, 2, 3, 4, 5);
List<Integer> doubleOfEven = new ArrayList<>();
numbers.stream()
.filter(e -> e % 2 == 0)
.map(e -> e * 2)
.forEach(e -> doubleOfEven.add(e));
然后他继续编写应该使用的代码,即:
List<Integer> doubleOfEven2 =
numbers.stream()
.filter(e -> e % 2 == 0)
.map(e -> e * 2)
.collect(toList());
我不明白为什么第一段代码是“坏习惯”。对我来说,他们都实现了相同的目标。
【问题讨论】:
-
使流并行,突然之间,顺序不再被遵守,或者更糟糕的是,由于多个线程在没有同步的情况下同时改变它,因此列表已损坏。第二个版本不会发生这种情况。
-
@JBNizet 在示例中不是因为
parallel(与结果集合的顺序无关),而是关于forEach。 -
@Eugene 没有共享,只有一个线程。所以,既然这是关于共享可变性,是的,这是关于并行的。是的,即使使用同步集合,使该代码并行,也会使集合的顺序不确定(实际上已经不能保证在没有并行的情况下具有确定的顺序,即使在实践中也是如此)。
-
@JBNizet 应该重新表述一下。由于应用了
parallel,所以没有顺序因为forEach。我的观点是并行/顺序并不决定顺序。是操作。 -
@Eugene 好的,我同意。
标签: java java-8 java-stream immutability