javadoc for java.util.stream
意味着流管道中的“行为操作”通常必须是无状态的。但是,该示例显示的有关如何不编写管道的示例似乎都涉及并行流。
这在多大程度上适用于顺序流?
特别是,我正在查看一个基本上看起来像这样的同事的代码:
List<SomeClass> list = ...;
Map<SomeClass, String> map = new HashMap<>();
list.stream()
.filter(x -> [some boolean expression])
.forEach(x -> {
if (map.containsKey(x) {
throw new UserDefinedException("duplicates detected in input");
} else {
map.put(x, aStringFunction(x));
}
});
[作者曾尝试使用
Collectors.toMap()
,但是当有重复项时,它抛出了IllegalStateException
,我们俩都不知道需要toMap
的mergeFunction
。最后一个本来是最好的解决方案,但是由于涉及到更广泛的原则,我还是想得到一个答案。]我对此代码感到不安,因为我不清楚
forEach
中的块的执行是否可以针对不同的元素重叠,即使对于顺序流也是如此。 javadoc for forEach()
不确定是否需要同步才能访问顺序流中的共享状态。最终,作者将代码更改为使用ConcurrentHashMap
和map.putIfAbsent()
。我的问题是:我应该紧张吗,还是该代码值得信赖?
假设
filter()
中的表达式做了一些使用某些共享状态的操作。我们可以相信使用顺序流时它可以正常工作吗? 最佳答案
按照定义,顺序流将执行调用程序线程中的所有操作,因此,如果将来不打算并行化流,则可以安全地使用共享状态,而无需其他同步和并发安全集合。因此,当前代码是安全的。但是请注意,它看起来很脏。