Parallel Stream 给出空项,如何在 Java 8 中执行

Parallel Stream gives null items, How to do in Java 8

我在尝试使用并行流时得到了一些奇怪的结果,我知道一个解决方法,但它似乎并不理想

// Create the set "selected"
somethingDao.getSomethingList().parallelStream()
                .filter(something -> !selected.contains(something.getSomethingId()))
                .forEach(something ->
                                somethingSubGroupDTO.addFilterDTO(
                                        new FilterDTO(something.getSomethingName(), something.getSomethingDescription(), false))
                );
selected.clear();

somethingDao.getSomethingListreturns一个List

selected 是在此操作期间未修改的 HashSet<Integer>

somethingSubGroupDTO.addFilterDTO 是添加到未同步列表的辅助函数。这就是问题。作为一个不同步的列表,我在列表中得到的项目比预期的要少,而且有些项目是空的。如果我把它变成一个同步列表,它就可以工作。显然在并行流中加入锁竞争是不理想的。

在高层次上,我知道可以通过这样一种方式来做到这一点,即每个流都将进行自己的处理,并且当它们加入时它们将聚合。 (至少我可以想象这样一个没有锁争用的过程)但是因为我是 Java 8 流处理的新手,所以我不知道如何处理。我如何在没有单点争用的情况下执行相同的操作?

不要使用 forEach 而是将您的流收集到 List 中:

somethingDao.getSomethingList().parallelStream()
                .filter(something -> !selected.contains(something.getSomethingId()))
                .map(something -> new FilterDTO(something.getSomethingName(), something.getSomethingDescription(), false))
                .collect(toList());

然后,您可以将返回的列表直接设置到您的 somethingSubGroupDTO 对象中,而不是一次添加一项。