我试过这段代码:
final List<ScheduleContainer> scheduleContainers = new ArrayList<>();
scheduleResponseContent.getSchedules().parallelStream().forEach(s -> scheduleContainers.addAll(s));
使用parallelStream,我得到一个ArrayIndexOutOfBoundException或NullpointerException,因为 scheduleContainers 中的某些条目为空。
使用... .stream()......一切正常。 我现在的问题是,是否有可能解决这个问题或者我是否误用了parallelStream?
答案 0 :(得分:7)
是的,你误用了parallelStream。首先,as you have already said twice in your previous question,默认情况下应使用stream(),而不是parallelStream()。并行具有内在成本,通常会使事情的效率低于简单的顺序流,除非您有一个大量数据要处理,并且每个元素的过程需要时间。您应该遇到性能问题,并在使用之前测量并行流是否解决了该问题。正如你的帖子所示,还有更大的机会搞乱并行流。
阅读Should I always use a parallel stream when possible?以获取更多参数。
其次,这段代码根本不是线程安全的,因为它使用几个并发线程来添加到线程不安全的ArrayList。如果您使用collect()为您创建最终列表而不是forEach()并且自己将内容添加到列表中,则可以是安全的。
代码应为
List<ScheduleContainer> scheduleContainers =
scheduleResponseContent.getSchedules().
.stream()
.flatMap(s -> s.stream())
.collect(Collectors.toList());
答案 1 :(得分:4)
不确定错误的原因,但有更好的方法可以使用Stream API从多个输入列表创建List。
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());