使用 Java8 流过滤 Map 的键后映射到列表

问题描述 投票:0回答:4

我有一个

Map<String, List<String>>
。我想在过滤地图的键后将此地图转换为列表。

示例:

Map<String, List<String>> words = new HashMap<>();
List<String> aList = new ArrayList<>();
aList.add("Apple");
aList.add("Abacus");

List<String> bList = new ArrayList<>();
bList.add("Bus");
bList.add("Blue");
words.put("A", aList);
words.put("B", bList);

给定一把钥匙,说“B”

Expected Output: ["Bus", "Blue"]

这就是我正在尝试的:

 List<String> wordsForGivenAlphabet = words.entrySet().stream()
    .filter(x-> x.getKey().equalsIgnoreCase(inputAlphabet))
    .map(x->x.getValue())
    .collect(Collectors.toList());

我收到错误。有人可以给我提供一种在 Java8 中做到这一点的方法吗?

java list java-8 hashmap collectors
4个回答
17
投票

您的片段将产生

List<List<String>>
而不是
List<String>

您缺少 flatMap ,它会将列表流转换为单个流,因此基本上会展平您的流:

List<String> wordsForGivenAlphabet = words.entrySet().stream()
    .filter(x-> x.getKey().equalsIgnoreCase(inputAlphabet))
    .map(Map.Entry::getValue)
    .flatMap(List::stream) 
    .collect(Collectors.toList());

如果您不希望值重复,还可以添加

distinct()


4
投票

Federico 在他的评论中是正确的,如果您想要的只是获取某个键的值(在

List
内),为什么不简单地执行
get
(假设所有键都已经是大写字母)?

 List<String> values = words.get(inputAlphabet.toUpperCase());

另一方面,如果这只是为了了解流操作是如何工作的,还有另一种方法可以实现(通过 java-9

Collectors.flatMapping

List<String> words2 = words.entrySet().stream()
            .collect(Collectors.filtering(x -> x.getKey().equalsIgnoreCase(inputAlphabet),
                    Collectors.flatMapping(x -> x.getValue().stream(), 
                          Collectors.toList())));

0
投票

正如之前所说,在

collect
之后,您将得到
List<List<String>>
,其中只有一个或零值。您可以使用
findFirst
代替
collect
,它将返回您
Optional<List<String>>


0
投票
List<String> items = words.entrySet().stream()
  .filter(entry -> entry.getKey().equals("B"))
  .flatMap(entry -> entry.getValue().stream())
  .collect(Collectors.toList());
  System.out.println(items);
© www.soinside.com 2019 - 2024. All rights reserved.