【问题标题】:Efficient way to create a list of specific values from a bunch of maps从一堆地图中创建特定值列表的有效方法
【发布时间】:2019-07-28 16:36:25
【问题描述】:

假设我有一张地图列表

List<Map<String, Double>> maps = new ArrayList<>();

Map<String, Double> map1 = new HashMap();
map1.put("height",60D);
map1.put("weight",144D);

maps.add(map1);


Map<String, Double> map2 = new HashMap();
map2.put("height",63D);
map2.put("weight",192D);

maps.add(map2);

等等……

创建身高或体重列表的最快方法是什么? 诸如列表高度之类的东西。

经典的方法是查看地图,使用 if 条件并搜索高度键,如果找到,则将其添加到返回列表中。

使用流的等效方法是什么?

【问题讨论】:

  • 它不应该编译,你有一个List&lt;HashMap&lt;String, Double&gt;&gt;,但添加Map&lt;String, Double&gt;s

标签: java list dictionary java-8 java-stream


【解决方案1】:
List<Double> listHeights = maps.stream()
                                .map(map -> map.get("height"))
                                .filter(Objects::nonNull)
                                .collect(Collectors.toList());

同样,您也可以为weight 这样做。

【讨论】:

  • 如果地图不包含密钥,会将null 添加到结果列表中
【解决方案2】:

您可以流式传输列表并将地图映射到相关值:

List<Double> heights =
    maps.stream()
        .filter(m -> m.containsKey("height"))
        .map(m -> m.get("height"))
        .collect(Collectors.toList());

【讨论】:

  • filtermap... 和containsKey 周围缺少几个右括号) 将是filter 中更好的选择
【解决方案3】:

如果您想同时获得heightweight 列表,则使用Collectors.groupingBy 不需要containsnull 检查

Map<String, List<Double>> result = maps.stream()
                                           .flatMap(m->m.entrySet().stream())
                                           .collect(Collectors.groupingBy(Map.Entry::getKey,
                                                   Collectors.mapping(Map.Entry::getValue, Collectors.toList())));

    result.forEach((k,v)->System.out.println(k+"..."+v));

输出

weight...[144.0, 192.0]
height...[60.0, 63.0]

您也可以使用getOrDefault 获取身高或体重的List

List<Double> height = result.getOrDefault("height", new ArrayList<Double>());

【讨论】:

    猜你喜欢
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-15
    • 2016-08-22
    • 2021-01-09
    • 1970-01-01
    • 2018-10-17
    相关资源
    最近更新 更多