您需要使用
flatMap将值展平到一个新的流中,但是由于仍然需要原始键来收集到中
Map,因此您必须映射到一个包含键和值的临时对象,例如
Map<String, Integer> mapTo = mapFrom.entrySet().stream() .flatMap(e->e.getValue().stream() .map(v->new AbstractMap.SimpleImmutableEntry<>(e.getKey(), v))) .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
的
Map.Entry是一个独立的为不存在的元组类型,能够保持不同类型的两个对象的任何其它类型的是足够的。
不需要这些临时对象的替代方法是自定义收集器:
Map<String, Integer> mapTo = mapFrom.entrySet().stream().collect( HashMap::new, (m,e)->e.getValue().forEach(v->m.put(v, e.getKey())), Map::putAll);
这不同于
toMap静默覆盖重复键,而
toMap如果没有重复键,则没有合并功能将引发异常。基本上,此自定义收集器是
Map<String, Integer> mapTo = new HashMap<>();mapFrom.forEach((k, l) -> l.forEach(v -> mapTo.put(v, k)));
但是请注意,即使输入图非常大,此任务也不会从并行处理中受益。只有在流管道中还有其他可以从SMP中受益的计算密集型任务时,才有可能从并行流中受益。因此,也许简洁的顺序Collection
API解决方案是可取的。



