Java 8 将 Map<Long, List<MyClass>> 流式传输到 Map<Long, Set<Long>>

lou*_*ros 1 java java-8 java-stream

我想将 a 转换(使用 Java 8 流),Map<Long, List<MyClass>>其中Map<Long, Set<Long>>代表Set<Long>每个.idMyClassList

我努力了:

myFirstMap.entrySet().stream()
      .map(e -> e.getValue().stream()
          .map(MyClass::getId)
          .collect(Collectors.toSet()))
Run Code Online (Sandbox Code Playgroud)

但我不知道如何得到结果。

Hol*_*ger 5

您将 的实例映射Map.Entry到Set<Long>实例,这意味着丢失原始映射\xe2\x80\x99s 键的跟踪,这使得无法将它们收集到具有相同键的新映射中。

\n\n

第一个选项是将Map.Entry<Long, List<MyClass>>实例映射到Map.Entry<Long, Set<Long>>实例,然后将条目收集到新映射:

\n\n
Map<Long, Set<Long>> result=\n    myFirstMap.entrySet().stream()\n        .map(e -> new AbstractMap.SimpleImmutableEntry<>(e.getKey(),\n               e.getValue().stream().map(MyClass::getId).collect(Collectors.toSet())))\n        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));\n
Run Code Online (Sandbox Code Playgroud)\n\n

另一种方法是将map和collect单步融合为一个,在提供给收集器的值函数中进行正确的转换toMap:

\n\n
Map<Long, Set<Long>> result=\n    myFirstMap.entrySet().stream().collect(Collectors.toMap(\n        Map.Entry::getKey,\n        e -> e.getValue().stream().map(MyClass::getId).collect(Collectors.toSet())));\n
Run Code Online (Sandbox Code Playgroud)\n\n

这样,您可以避免创建新Map.Entry实例并获得更简洁的代码,但是,灵活性会降低,因为您可以\xe2\x80\x99t在其间链接其他流操作。

\n