Java Streams将EnumMap的Map转换为列表Map

时间:2016-06-28 20:35:54

标签: java collections lambda java-8 java-stream

我希望转换以下内容

enum Parameter {Foo, Bar, Baz};

Map<String, EnumMap<Parameter, String>> myMap = new HashMap(){{
   put("KEY1", new EnumMap<>(Parameter.class) {{
      put(Parameter.Foo, "BAD");
      put(Parameter.Bar, "GOOD");
      put(Parameter.Baz, "BAD");
   }});
   put("KEY2", new EnumMap<>(Parameter.class) {{
      put(Parameter.Foo, "BAD");
      put(Parameter.Bar, "GOOD");
      put(Parameter.Baz, "GOOD");
   }});
}};

进入过滤后的地图,其中过滤器只包含

Map<String, List<Entry<Parameter, String>>> mapList

结果列表应包含“GOOD”作为过滤条件的行。

我无法弄清楚正确的流语法,我知道它的行如下:

Map<String, List<Entry<Parameter, String>>> mapList =
    myMap.entrySet().stream().groupingBy(e -> e.getKey()).collect(Collectors.toMap(????)

2 个答案:

答案 0 :(得分:3)

目前尚不清楚为什么要强调值的x性质,因为在使用特定EnumMap类型时逻辑不会改变。您有一个要转换的值的地图,保留键,这意味着通过条目流式传输并通过Map收集是要走的路,让键功能返回原始键,值函数执行实际转换。

值恰好是Collectors.toMap,您希望将其转换为Map,这非常简单,可以在条目上进行流式处理并将其收集到List<Map.Entry>。添加过滤器仅接受List值是微不足道的。

现在,你很遗憾buried another important requirement in a comment而不是在问题中指明它。如果目标地图中没有"GOOD"值,则您希望省略外部地图的键。所以你需要一个用于外部流操作的过滤器,如果你还记得Collection API有多强大,即使没有Streams也需要一个过滤器:

"GOOD"

答案 1 :(得分:2)

这些条目已经正确分组,只需要解包并过滤这些值:

import static java.util.stream.Collectors.*;
...
Map<String, List<Entry<Parameter, String>>> mapList = new HashMap<>();

myMap.forEach((k, v) -> { 
   List<Entry<Parameter, String>> filtered = v.entrySet().stream()
   .filter(e -> e.getValue().equals("GOOD"))
   .collect(toList());

   if(!filtered.isEmpty()) mapList.put(k, filtered);
});