来自“地图 >“到”地图 >“使用Java 8

问题描述 投票:2回答:3

有没有更好的方法将“Map <String,Collection <String >>”转换为“Map <String,List <String >>”?

Map<String, Collection<String>> collectionsMap = ...
Map<String, List<String>> listsaps =
    collectionsMap.entrySet().stream()
    .collect(Collectors.<Map.Entry<String, Collection<String>>,
        String, List<String>>toMap(
            Map.Entry::getKey,
            e -> e. getValue().stream().collect(Collectors.toList())
        )
    );

感谢您帮助我们改进

java java-stream collectors entryset
3个回答
4
投票

对于这样的情况,我会考虑使用Map.forEach来执行使用副作用的操作。地图上的流有点麻烦,因为需要编写额外的代码来流式传输地图条目,然后从每个条目中提取密钥和值。相比之下,Map.forEach将每个键和值作为单独的参数传递给函数。这是看起来像:

Map<String, Collection<String>> collectionsMap = ...
Map<String, List<String>> listsaps = new HashMap<>(); // pre-size if desired
collectionsMap.forEach((k, v) -> listsaps.put(k, new ArrayList<>(v)));

如果您的地图很大,您可能希望预先确定目的地的大小,以避免在其填充期间进行重新布局。要做到这一点,你必须知道HashMap将桶的数量,而不是元素的数量作为其参数。这需要除以默认的载荷因子0.75,以便在给定一定数量的元素的情况下适当地预先调整大小:

Map<String, List<String>> listsaps = new HashMap<>((int)(collectionsMap.size() / 0.75 + 1));

3
投票

1)在Collectors.toMap()中,您不需要重复通用类型,因为这些是推断的。

所以:

collect(Collectors.<Map.Entry<String, Collection<String>>,
        String, List<String>>toMap(...)

可以替换为:

collect(Collectors.toMap(...)

2)也可以简化将集合转换为List的方法。

这个 :

e -> e. getValue().stream().collect(Collectors.toList())

可以写成:

e -> new ArrayList<>(e.getValue())

你可以写:

Map<String, List<String>> listsaps =
            collectionsMap.entrySet()
            .stream()
            .collect(Collectors.toMap(
                    Map.Entry::getKey,
                    e -> new ArrayList<>(e.getValue())
                )
            );

1
投票

我认为这更容易阅读:

Map<String, List<String>> listsaps = new HashMap<>();
collectionsMap.entrySet()
    .stream()
    .forEach(e -> listsaps.put(e.getKey(), new ArrayList<>(e.getValue())));

如果您只想将条目转换为列表但不关心更改集合的类型,那么您可以使用map.replaceAll

collectionsMap.replaceAll((k, v) -> new ArrayList<>(v));
© www.soinside.com 2019 - 2024. All rights reserved.