我想在Map<Long, List<MyClass>>
转换(使用Java 8流)Map<Long, Set<Long>>
,其中Set<Long>
代表每个id
的{{1}} MyClass
。
我试过了:
List
但我看不出如何得到结果。
答案 0 :(得分:4)
您正在将Map.Entry
的实例映射到Set<Long>
个实例,这意味着无法跟踪原始地图的键,这使得无法将它们收集到具有相同键的新地图中。
第一个选项是将Map.Entry<Long, List<MyClass>>
个实例映射到Map.Entry<Long, Set<Long>>
个实例,然后将条目收集到新地图中:
Map<Long, Set<Long>> result=
myFirstMap.entrySet().stream()
.map(e -> new AbstractMap.SimpleImmutableEntry<>(e.getKey(),
e.getValue().stream().map(MyClass::getId).collect(Collectors.toSet())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
另一种方法是将map
和collect
步骤合并为一个,在提供给toMap
收集器的值函数中进行转换:
Map<Long, Set<Long>> result=
myFirstMap.entrySet().stream().collect(Collectors.toMap(
Map.Entry::getKey,
e -> e.getValue().stream().map(MyClass::getId).collect(Collectors.toSet())));
这样,您可以避免创建新的Map.Entry
实例并获得更简洁的代码,但是,由于无法在其间链接其他流操作,因此松散的灵活性。
答案 1 :(得分:0)
另一个解决方案,没有外部Stream
的开销,就是像这样使用Map.forEach()
:
Map<Long,Set<Long>> result = new HashMap<>();
myFirstMap.forEach((k,v) ->
result.put(k, v.stream()
.map(MyClass::getId)
.collect(Collectors.toSet())));
这实际上只是一种方便的方法:
Map<Long,Set<Long>> result = new HashMap<>();
for (Map.Entry<Long, List<MyClass>> entry : myFirstMap.entrySet()) {
result.put(entry.getKey(), entry.getValue().stream()
.map(MyClass::getId)
.collect(Collectors.toSet()));
}