[英]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.