假设我有以下地图列表,
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))));
有人可以告诉我该怎么做吗?
提前致谢。
答案 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
方法为已存在的密钥选择最小值。