使用收集到.但是,使用起来并不安全,并且消费者将东西添加到.parallelStream()
HashMap
parallelStream()
forEach
HashMap
HashMap
不是同步类,并且尝试同时在其中放置元素将无法正常工作。这就是 forEach
将要执行的操作,它将调用给定的使用者,该使用者可能同时从多个线程将元素放入 中。如果你想要一个简单的代码来演示这个问题:HashMap
List<Integer> list = IntStream.range(0, 10000).boxed().collect(Collectors.toList());
Map<Integer, Integer> map = new HashMap<>();
list.parallelStream().forEach(i -> {
map.put(i, i);
});
System.out.println(list.size());
System.out.println(map.size());
确保运行它几次。很有可能(并发的乐趣),操作后的打印地图大小不是10000,这是列表的大小,但略小。
这里的解决方案,一如既往,不是使用 ,而是使用方法和内置的toMap
的可变约简方法:forEach
collect
Map<Integer, Integer> map = list.parallelStream().collect(Collectors.toMap(i -> i, i -> i));
在上面的示例代码中使用该行代码,您可以放心,映射大小将始终为 10000。流 API 确保可以安全地收集到非线程安全容器中,即使并行也是如此。这也意味着你不需要使用toConcurrentMap
来确保安全,如果你特别想要一个结果,而不是一般的;如果你特别想要一个结果,那么这个收集器是需要的;但就线程安全性而言,您可以同时使用两者。ConcurrentMap
Map
collect