Java 8:将具有字符串值的映射转换为包含不同类型的列表
Posted
技术标签:
【中文标题】Java 8:将具有字符串值的映射转换为包含不同类型的列表【英文标题】:Java 8: Convert a map with string values to a list containg a different type 【发布时间】:2016-02-29 14:36:17 【问题描述】:我有这个Map
:
Map<Integer, Set<String>> map = ...
我有这门课Foo
:
class Foo
int id;
String name;
我想将地图转换为List<Foo>
。 Java 8 中是否有方便的方式来执行此操作?
目前,我的方式是:
List<Foo> list = new ArrayList<>((int) map.values().flatMap(e->e.stream()).count()));
for(Integer id : map.keySet())
for(String name : map.get(id))
Foo foo = new Foo(id,name);
list.add(foo);
我觉得太麻烦了。
【问题讨论】:
How to convert a Map to List in Java?的可能重复 不,它不是重复的。 @zhugowei 我必须同意你的观点。我已经编辑了问题以防止误解。 【参考方案1】:你的版本比较麻烦的主要原因是你决定先计算ArrayList
的容量。由于此计算需要遍历整个地图,因此不太可能有任何好处。你绝对不应该做这样的事情,除非你已经使用适当的基准证明它是必要的。
我看不出仅使用您的原始版本但使用ArrayList
的无参数构造函数有什么问题。如果你还去掉了多余的局部变量foo
,它实际上比流版本的字符更少(并且更清晰)。
【讨论】:
是的,你是对的。但是不优化很难忍住【参考方案2】:final Map<Integer, Set<String>> map = new HashMap<>();
map
.entrySet()
.stream()
.flatMap(e -> e.getValue().stream().map(s -> new Foo(e.getKey(), s)))
.collect(Collectors.toList());
【讨论】:
【参考方案3】:您可以拥有以下内容:
List<Foo> list = map.entrySet()
.stream()
.flatMap(e -> e.getValue().stream().map(name -> new Foo(e.getKey(), name)))
.collect(toList());
对于映射的每个条目,我们创建一个值的 Stream 并将其映射到对应的 Foo
,然后使用 flatMap
将其展平。
【讨论】:
以上是关于Java 8:将具有字符串值的映射转换为包含不同类型的列表的主要内容,如果未能解决你的问题,请参考以下文章