[英]Java Streams transform Map of EnumMap into a Map of lists
我想转换以下内容
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(????)
目前尚不清楚为什么要强调值的EnumMap
性质,因为使用该特定Map
类型时逻辑不会改变。 您有一个要转换其值的地图,保留了键,这意味着流式处理条目并通过Collectors.toMap
是Collectors.toMap
的方法,让键函数返回原始键,而value函数进行实际转换。
这些值碰巧是一个Map
,您想将其转换为List<Map.Entry>
,这很容易,将条目流式传输并将其收集到List
。 添加过滤器仅接受"GOOD"
值很简单。
现在,很遗憾您在注释中埋入了另一个重要的要求,而不是在问题中指定它。 如果目标地图中根本没有"GOOD"
值, "GOOD"
忽略外部地图的键。 因此,如果您记得即使没有Streams,Collection API的功能也很强大,那么就需要一个用于外部流操作的过滤器,这并不难。
Map<String, List<Map.Entry<Parameter, String>>> mapList
= myMap.entrySet().stream()
.filter(e -> e.getValue().containsValue("GOOD")) // need at least one GOOD there
.collect(Collectors.toMap(
Map.Entry::getKey, // keep original keys
e -> e.getValue().entrySet().stream() // actual conversion
.filter(sub -> sub.getValue().equals("GOOD")) // GOOD values only
.collect(Collectors.toList()) // make List<Map.Entry>
));
条目已正确分组,仅需要解包和过滤值:
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);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.