Java 8 stream Map <long,list <myclass =“”>&gt;映射<long,set <long =“”>&gt;

时间:2016-05-12 07:53:10

标签: java java-8 java-stream

我想在Map<Long, List<MyClass>>转换(使用Java 8流)Map<Long, Set<Long>>,其中Set<Long>代表每个id的{​​{1}} MyClass

我试过了:

List

但我看不出如何得到结果。

2 个答案:

答案 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));

另一种方法是将mapcollect步骤合并为一个,在提供给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()));
}