Java-8 parallelStream(...) - > fill ArrayList

qum*_*uma 3 java-8 java-stream

我试过这段代码:

 final List<ScheduleContainer> scheduleContainers = new ArrayList<>();
 scheduleResponseContent.getSchedules().parallelStream().forEach(s -> scheduleContainers.addAll(s));
Run Code Online (Sandbox Code Playgroud)

使用parallelStream,我得到一个ArrayIndexOutOfBoundException或NullpointerException,因为scheduleContainers中的一些条目为null.

使用... .stream()......一切正常.我现在的问题是,如果有可能解决这个问题,或者我是否误用了parallelStream?

JB *_*zet 8

是的,你误用了parallelStream.首先,正如您在上一个问题中已经说过两次,默认情况下应该使用stream(),而不是parallelStream().并行具有内在成本,通常会使事情的效率低于简单的顺序流,除非您有大量要处理的数据,并且每个元素的过程都需要时间.您应该遇到性能问题,并在使用之前测量并行流是否解决了该问题.正如你的帖子所示,还有更大的机会搞乱并行流.

读取我是否应该尽可能使用并行流?更多的论点.

其次,这段代码根本不是线程安全的,因为它使用几个并发线程来添加到线程不安全的ArrayList.如果您使用collect()为您创建最终列表而不是forEach()并自行添加到列表中,则可以是安全的.

代码应该是

List<ScheduleContainer> scheduleContainers =
    scheduleResponseContent.getSchedules().
                           .stream()
                           .flatMap(s -> s.stream())
                           .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)


Era*_*ran 5

不确定错误的原因,但是有更好的方法来使用Stream API从多个输入列表创建列表。

final List<ScheduleContainer> scheduleContainers =
    scheduleResponseContent.getSchedules()
                           .parallelStream()
                           .flatMap(s->s.stream()) // assuming getSchedules() returns some 
                                                   // Collection<ScheduleContainer>, based 
                                                   // on your use of addAll(s)
                           .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)