![](/img/trans.png)
[英]Create only 1 list from a map where map value is list using JAVA 8 Streams
[英]Java Map with List value to list using streams?
我正在嘗試使用流重寫下面的方法,但我不確定最好的方法是什么? 如果我在entrySet()
的值上使用flatMap
,我會丟失對當前鍵的引用。
private List<String> asList(final Map<String, List<String>> map) {
final List<String> result = new ArrayList<>();
for (final Entry<String, List<String>> entry : map.entrySet()) {
final List<String> values = entry.getValue();
values.forEach(value -> result.add(String.format("%s-%s", entry.getKey(), value)));
}
return result;
}
我設法做的最好的事情如下:
return map.keySet().stream()
.flatMap(key -> map.get(key).stream()
.map(value -> new AbstractMap.SimpleEntry<>(key, value)))
.map(e -> String.format("%s-%s", e.getKey(), e.getValue()))
.collect(Collectors.toList());
有沒有更簡單的方法而無需創建新的Entry
對象?
stream 是一個值序列(可能是無序的/並行的)。 當您想將序列中的單個值 map 轉換為某個其他值時,您可以使用map()
。 比如說,map“alturkovic”到“ALTURKOVIC”。 當您想將序列中的單個值 map 轉換為 0、1 或許多其他值時,您可以使用flatMap()
。 因此為什么 flatMap lambda 需要將值轉換為值的 stream。 因此,flatMap 可用於獲取字符串列表的列表,並將其轉換為僅包含字符串的 stream。
在這里,您希望將 map(單個鍵/值對)中的單個條目 map 轉換為單個元素(描述它的字符串)。 1 值到 1 值。 這意味着flatMap 不合適。 您正在尋找的只是 map。
此外,您需要 key 和 value 來執行映射操作,因此keySet() 也不合適。 您正在尋找entrySet()
,它為您提供了一組所有 k/v 對,正是我們需要的。
這讓我們:
map.entrySet().stream()
.map(e -> String.format("%s-%s", e.getKey(), e.getValue()))
.collect(Collectors.toList());
您的原始代碼沒有努力將 map (這是一個List<String>
)中的單個值視為單獨的值; 您只需在整個考驗中調用.toString()
即可。 這意味着生成的字符串看起來像[Hello, World]
給定的 map 值List.of("Hello", "World")
。 如果你不想要這個,你仍然不想要 flatmap,因為流也是同質的 - stream 中的值都是相同的,因此“key1 value1 value2 key2 valueA valueB”的 stream 不是什么你想要:
map.entrySet().stream()
.map(e -> String.format("%s-%s", e.getKey(), myPrint(e.getValue())))
.collect(Collectors.toList());
public static String myPrint(List<String> in) {
// write your own algorithm here
}
Stream API 不是替代 myPrint 方法的正確工具。
第三種選擇是您想要塗抹 map; 您希望 mapvalue 的List<String>
中的每個字符串首先與鍵匹配(因此重新說明該鍵相當多),然后對此做一些事情。 現在flatMap是合適的 - 你首先想要一個 k/v 對的 stream ,然后對此做一些事情,每個元素現在都是同一種。 您要轉動 map:
key1 = [value1, value2]
key2 = [value3, value4]
首先進入 stream:
key1:value1
key1:value2
key2:value3
key2:value4
並從那里拿走。 這會將 map 中的單個 k/v 條目分解為多個,因此需要平面映射:
return map.entrySet().stream()
.flatMap(e -> e.getValue().stream()
.map(v -> String.format("%s-%s", e.getKey(), v))
.collect(Collectors.toList());
從內到外,它將列表中屬於單個 k/v 對的單個條目映射到字符串Key-SingleItemFromItsList
中。
將我的兩美分添加到@rzwitserloot 的出色答案中。 在他的回答中已經解釋了平面圖和 map。
List<String> resultLists = myMap.entrySet().stream()
.flatMap(mapEntry -> printEntries(mapEntry.getKey(),mapEntry.getValue())).collect(Collectors.toList());
System.out.println(resultLists);
將其拆分為單獨的方法可提供良好的可讀性 IMO,
private static Stream<String> printEntries(String key, List<String> values) {
return values.stream().map(val -> String.format("%s-%s",key,val));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.