使用Java 8 Streams将地图映射转换为列表 [英] Convert Map of maps into Lists using Java 8 Streams

查看:68
本文介绍了使用Java 8 Streams将地图映射转换为列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一张地图:

Map<String, Map<Integer, List<Integer>>>
e.g. Map<Name, Map<Id, List<ReferenceId>>>

Outcome:
List<Id>
List<ReferenceId>

我想将此地图转换为两个整数列表。一个列表包含内部映射键,另一个列表包含内部映射值(即列表<整数>

I wanna convert this map into two list of Integers. One list contains inner-map keys, and other contains inner-map value (i.e. List<Integer>)

任何人都可以告诉我如何使用流在Java 8中执行此操作?

Can anyone tell me how to do this in Java 8 using streams?

我试过这种方式但得到了Cast Exception,无法将String转换为Integer。

I tried this way but got Cast Exception, can not convert String to Integer.

map.values().stream()
    .map(m -> m.entrySet()
    .stream()
    .map(e -> e.getKey())
    .collect(Collectors.toList()))
    .flatMap(l -> l.stream())
    .collect(Collectors.toList());


推荐答案

没有办法,你的代码如何

There is no way, how your code

List<Integer> list = map.values().stream()
    .map(m -> m.entrySet().stream()
            .map(e -> e.getKey())
            .collect(Collectors.toList()))
    .flatMap(l -> l.stream())
    .collect(Collectors.toList());

可以产生 ClassCastException ,除非你管理在 Stream操作之前,通过未经检查的操作将错误类型的对象插入到源映射中。这种情况称为堆污染,您应该在启用所有警告的情况下编译整个代码( javac :使用选项 - Xlint:未经检查)并解决它们。

can produce a ClassCastException, unless you managed to insert objects of wrong type into the source map via unchecked operation(s) before the Stream operation. Such a situation is called heap pollution and you should compile your entire code with all warnings enabled (javac: use option -Xlint:unchecked) and solve them.

但请注意,您的代码不必要地复杂化。链, .entrySet()。stream()。map(e - > e.getKey())是在条目上流式传输并映射到键,所以你可以首先流式传输密钥,即 .keySet()。stream()。然后,您将流收集到 List 中,只是为了在次要的<$ c中调用 .stream() $ c> flatMap 步骤,因此您只需使用您已有的流:

But note that your code is unnecessarily complicated. The chain, .entrySet().stream().map(e -> e.getKey()) is streaming over the entries and mapping to the keys, so you can stream over the keys in the first place, i.e. .keySet().stream(). Then, you are collecting the stream into a List, just to invoke .stream() in the subequent flatMap step, so you can simply use the stream you already have instead:

List<Integer> list = map.values().stream()
    .flatMap(m -> m.keySet().stream())
    .collect(Collectors.toList());

或者,您可以让收藏家完成所有工作:

Alternatively, you can let the collector do all the work:

List<Integer> list = map.values().stream()
    .collect(ArrayList::new, (l,m) -> l.addAll(m.keySet()), List::addAll);

获取值而不是键的工作方式类似,但需要另一个 flatMap 步骤获取列表元素:

Getting the values instead of the keys works similar, but requires another flatMap step to get the List elements:

List<Integer> list = map.values().stream()
    .flatMap(m -> m.values().stream().flatMap(List::stream))
    .collect(Collectors.toList());

相当于

List<Integer> list = map.values().stream()
    .flatMap(m -> m.values().stream())
    .flatMap(List::stream)
    .collect(Collectors.toList());

同样,还有让收藏家完成所有工作的替代方案:

Again, there’s the alternative of letting the collector do all the work:

List<Integer> list = map.values().stream()
    .collect(ArrayList::new, (l,m)->m.values().forEach(l::addAll), List::addAll);

List<Integer> list = map.values().stream()
    .collect(ArrayList::new, (l,m)->m.forEach((k,v)->l.addAll(v)), List::addAll);

这篇关于使用Java 8 Streams将地图映射转换为列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆