Java 8:将具有字符串值的映射转换为包含不同类型的列表

Java 8: Convert a map with string values to a list containg a different type

我有这个Map:

Map<Integer, Set<String>> map = ...

我有这个 class 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);  
    }
}

感觉太麻烦了

您可以拥有以下内容:

List<Foo> list = map.entrySet()
                    .stream()
                    .flatMap(e -> e.getValue().stream().map(name -> new Foo(e.getKey(), name)))
                    .collect(toList());

对于映射的每个条目,我们创建一个值的 Stream 并将其映射到相应的 Foo,然后使用 flatMap.

将其展平
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());

你的版本繁琐的主要原因是你决定先计算ArrayList的容量。由于此计算需要遍历整个地图,因此不太可能有任何好处。你绝对不应该做这样的事情,除非你已经使用适当的基准证明它是必要的。

我看不出只使用您的原始版本有什么问题,而是使用 ArrayList 的无参数构造函数。如果你也去掉多余的局部变量foo,它实际上比流版本的字符更少(而且更易读)。