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,我们俩都不知道需要toMapmergeFunction。最后一个本来是最好的解决方案,但是由于涉及到更广泛的原则,我还是想得到一个答案。]

我对此代码感到不安,因为我不清楚forEach中的块的执行是否可以针对不同的元素重叠,即使对于顺序流也是如此。 javadoc for forEach()不确定是否需要同步才能访问顺序流中的共享状态。最终,作者将代码更改为使用ConcurrentHashMapmap.putIfAbsent()

我的问题是:我应该紧张吗,还是该代码值得信赖?

假设filter()中的表达式做了一些使用某些共享状态的操作。我们可以相信使用顺序流时它可以正常工作吗?

最佳答案

按照定义,顺序流将执行调用程序线程中的所有操作,因此,如果将来不打算并行化流,则可以安全地使用共享状态,而无需其他同步和并发安全集合。因此,当前代码是安全的。但是请注意,它看起来很脏。

10-06 03:40