请参阅下面的简单示例,该示例计算列表中每个单词的出现次数:
Stream<String> words = Stream.of("a", "b", "a", "c");
Map<String, Integer> wordsCount = words.collect(toMap(s -> s, s -> 1,
(i, j) -> i + j));
Run Code Online (Sandbox Code Playgroud)
最后,wordsCount是{a=2, b=1, c=1}.
但我的流非常大,我想要并行工作,所以我写道:
Map<String, Integer> wordsCount = words.parallel()
.collect(toMap(s -> s, s -> 1,
(i, j) -> i + j));
Run Code Online (Sandbox Code Playgroud)
但是我注意到这wordsCount很简单HashMap所以我想知道我是否需要明确要求并发映射以确保线程安全:
Map<String, Integer> wordsCount = words.parallel()
.collect(toConcurrentMap(s -> s, s -> 1,
(i, j) -> i + j));
Run Code Online (Sandbox Code Playgroud)
非并发收集器是否可以安全地与并行流一起使用,还是在从并行流收集时只应使用并发版本?
我有一个像这样的测试代码:
List<Integer> list = new ArrayList<>(1000000);
for(int i=0;i<1000000;i++){
list.add(i);
}
List<String> values = new ArrayList<>(1000000);
list.stream().forEach(
i->values.add(new Date().toString())
);
System.out.println(values.size());
Run Code Online (Sandbox Code Playgroud)
运行这个,我得到了一个正确的输出:1000000.
但是,如果我将其更改stream()为parallelStream(),则:
list.parallelStream().forEach(
i->values.add(new Date().toString())
);
Run Code Online (Sandbox Code Playgroud)
我有一个随机输出,例如:920821.
怎么了?