如何使用 Java 8 流从地图列表中找到每个用户的最低分数

How to find the minimum score of each user from a list of maps using Java 8 stream

假设我有以下地图列表,

List<Map<String, Integer>> scores = new ArrayList<>();

scores.add(Collections.singletonMap("user1", 3));
scores.add(Collections.singletonMap("user3", 15));
scores.add(Collections.singletonMap("user1", 1));
scores.add(Collections.singletonMap("user2", 5));
scores.add(Collections.singletonMap("user2", 23));
scores.add(Collections.singletonMap("user1", 10));

我想使用 Java 8 流和 lambda 表达式将每个用户的最低分数提取到地图中。期望的结果是

{user1=1, user2=5, user3=15}

我试过了,没用,

Map<String, Integer> result = scores.stream()
    .flatMap(m -> m.entrySet().stream())
    .collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.minBy(Comparator.comparingInt(Map.Entry::getValue))));

有人能告诉我怎么做吗?

提前致谢。

minBy 下游收集器 returns Optional<Entry<String, Integer>>,但您只需要 Integer。所以你应该使用 Collectors.collectingAndThen to adapt a downstream collector. Also consider using Map.Entry.comparingByValue() 静态方法。

Map<String, Integer> result = scores
        .stream()
        .flatMap(m -> m.entrySet().stream())
        .collect(Collectors.groupingBy(Map.Entry::getKey,
            Collectors.collectingAndThen(
                Collectors.minBy(Map.Entry.comparingByValue()),
                opt -> opt.get().getValue())));
Map<String, Integer> result = 
    scores.stream()
          .flatMap(map -> map.entrySet().stream())
          .collect(Collectors.toMap(Map.Entry::getKey,
                                    Map.Entry::getValue,
                                    Math::min));

另一种方式,不使用流,但具有 Java 8 个功能:

Map<String, Integer> result = new HashMap<>();
scores.forEach(map -> map.forEach((k, v) -> result.merge(k, v, Integer::min)));

这使用 Map.merge 方法 select 已存在键的最小值。