使用Java8流过滤Map的密钥后映射到List

时间:2017-07-18 21:13:16

标签: java list java-8 hashmap collectors

我有Map<String, List<String>>。我希望在地图密钥上过滤后将此地图转换为List。

示例:

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);

给出一个关键,比如,&#34; B&#34;

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

这就是我的尝试:

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

我收到了错误消息。有人可以在Java8中为我提供一种方法吗?

3 个答案:

答案 0 :(得分:12)

您的代码片段会生成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()

答案 1 :(得分:3)

Federico的评论是正确的,如果您只想获得某个键的值(在controlMethod内),为什么不简单地执行List(假设所有键都是是大写字母)?

get

另一方面,如果只是为了理解流操作是如何工作的,还有一种方法可以做到(通过java-9 List<String> values = words.get(inputAlphabet.toUpperCase());

Collectors.flatMapping

答案 2 :(得分:0)

正如之前在collect之后被告知的那样,您将获得List<List<String>>,其中只有一个或零值。您可以使用findFirst代替collect,它会返回Optional<List<String>>