我想通过Java 8 Map
和ConcurrentHashMap
界面将Stream
转换为Collector
,我可以使用两个选项。
第一个:
Map<Integer, String> mb = persons.stream()
.collect(Collectors.toMap(
p -> p.age,
p -> p.name,
(name1, name2) -> name1+";"+name2,
ConcurrentHashMap::new));
第二个:
Map<Integer, String> mb1 = persons.stream()
.collect(Collectors.toConcurrentMap(
p -> p.age,
p -> p.name));
哪一个是更好的选择?我什么时候应该使用每个选项?
答案 0 :(得分:9)
处理并行流时,它们之间存在差异。
toMap
- &gt;是非并发收集器
toConcurrentMap
- &gt;是一个并发收集器(这可以从他们的特征中看出来。)
区别在于 toMap 会创建多个中间结果然后合并在一起(这样的收集器的供应商将被多次调用),而 toConcurrentMap 将创建一个单个结果,每个Thread都会向它抛出结果(这样一个收集器的供应商只会被调用一次)
为什么这很重要?这涉及插入顺序(如果重要)。
toMap 将通过合并多个中间结果在遭遇顺序中在结果Map中插入值(该收集器的供应商被多次调用以及组合器)
toConcurrentMap 将通过将所有元素抛出到公共结果容器(在本例中为ConcurrentHashMap)以任何顺序(未定义)收集元素。供应商只召集一次,Accumulator多次召唤,而Combiner永远不召唤。
这里的一个小警告是,CONCURRENT
收集器不能调用合并:要么流必须有UNORDERED
标志 - 要么通过unordered()
显式调用,要么流的源不是有序的(例如Set
)。
答案 1 :(得分:5)
来自toMap
&#39; Javadoc:
返回的收集器不是并发的。对于并行流管道,组合器功能通过将键从一个映射合并到另一个映射来操作,这可能是昂贵的操作。如果不需要将结果以遭遇顺序插入到Map中,则使用toConcurrentMap(Function,Function)可以提供更好的并行性能。
toConcurrentMap
不会在遇到顺序的情况下将结果插入到地图中,但应该会提供更好的效果。
如果您不关心广告订单,建议您在使用并行广告时使用toConcurrentMap
。