在 Map<String、List 中查找最小值<Integer>>而不依赖于 for 循环



我有一个类型为HashMap<String, List<Integer>>的地图。

我想找到每个映射条目的最大值,然后找到这些最大值最小值

我知道这可以用几个for循环来完成。但我想知道是否有另一种方法(可能是流?)

我要找的最终结果是一个整数。

例子:

HashMap<String, List<Integer>> values = new HashMap<>();
values.put("a", Arrays.asList(4, 8, 9, 10)); // max value is 10
values.put("b", Arrays.asList(20, 32, 1, 2)); // max value is 32
values.put("c", Arrays.asList(11, 50, 20, 6)); // max value is 50
// I need the min value out of the above maximums i.e. 10 (final answer)

可以使用Collections方法。min和Collections.max

HashMap<String, List<Integer>> myMap = new HashMap<>();
Integer min = Collections.min(myMap.values().stream().map(Collections::max).collect(Collectors.toList()));

我想找到每个地图条目的最大值,然后再找到这些最大值中的最小值。

那么IntSummaryStatistics就是你的新朋友。该对象用于提供minmax值、所消耗元素的数量、平均值及其总数等信息。

作为结果的容器,可以使用mapMap<String, IntSummaryStatistics>来保存映射到该值的键的每个值的统计信息。为此,我们需要flatMapping()summarizingInt()收集器的帮助。

为了得到最小最大值,我们应该处理这个映射的值。
Map<String, List<Integer>> sourceMap = 
Map.of("a", List.of(4, 8, 9, 10),    // max value is 10
"b", List.of(20, 32, 1, 2),   // max value is 32
"c", List.of(11, 50, 20, 6)); // max value is 50

Map<String, IntSummaryStatistics> statisticsByKey = sourceMap.entrySet().stream()
.collect(Collectors.groupingBy(
Map.Entry::getKey,
Collectors.flatMapping(entry -> entry.getValue().stream(), // flatens each list
Collectors.summarizingInt(Integer::intValue))          // creates IntSummaryStatistics object based on the values of each list
));

statisticsByKey.forEach((k, v)
-> System.out.println(k + " -> min: " + v.getMin() + " max: " + v.getMax()));

int smallestMaximum = statisticsByKey.values().stream()
.mapToInt(IntSummaryStatistics::getMax)
.min()        // produces OptionalInt as a result
.orElse(-1);  // returns a default value of `-1` if result is not present

System.out.println("smallestMaximum: " + smallestMaximum);

输出:

a -> min: 4 max: 10
b -> min: 1 max: 32
c -> min: 6 max: 50
smallestMaximum: 10

链接在线演示

给定地图

Hash<String, List<Integer>> values;

找出每个列表的最大值,然后使用IntStreammin()对它们:

Integer minMax = values.values().stream()
.map(Collections::max)
.mapToInt(n -> n).min().getAsInt();

查看从样本数据中查找10的实时演示。


对于IntStream版本(可能更有效),流式处理值(即整数列表),然后通过将每个列表转换为IntStream并获得其最大值来找到每个列表的最大值,然后找到其中的最小值:

Integer minMax = values.values().stream()
.mapToInt(v -> v.stream().mapToInt(n -> n).max().getAsInt())
.min().getAsInt();

查看现场演示

假设所有列表都不为空,并且映射本身也不为空。


还有一种方法可以使用Collections.max(), but produces anOptional ',这是一种稍微迟钝的方法IMHO

Integer minMax = values.values().stream()
.map(Collections::max)
.collect(Collectors.minBy(Integer::compareTo)).get();

查看现场演示

最新更新