【发布时间】:2015-08-02 01:03:59
【问题描述】:
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() 中的表达式使用了一些共享状态。我们可以相信它在使用顺序流时可以正常工作吗?
【问题讨论】:
-
我不会相信任何操纵状态的东西。尽可能避免它。
标签: java java-8 java-stream