如何使用Java 8流

时间:2015-08-20 06:03:51

标签: lambda java-8 java-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));

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

{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))));

有人可以告诉我该怎么做吗?

提前致谢。

3 个答案:

答案 0 :(得分:6)

Map<String, Integer> result = 
    scores.stream()
          .flatMap(map -> map.entrySet().stream())
          .collect(Collectors.toMap(Map.Entry::getKey,
                                    Map.Entry::getValue,
                                    Math::min));

答案 1 :(得分:5)

minBy下游收集器返回Optional<Entry<String, Integer>>,但您只需要Integer。因此,您应该使用Collectors.collectingAndThen来适应下游收集器。另请考虑使用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())));

答案 2 :(得分:0)

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

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

这使用Map.merge方法为已存在的密钥选择最小值。