在不依赖 for 循环的 Map<String, List<Integer>> 中找到最大值的最小值

Find the Min of Max values in a Map<String, List<Integer>> without relying on for loops

我有一张类型为 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)

给定一张地图

Hash<String, List<Integer>> values;

找到每个列表的最大值,然后对这些使用 IntStreammin()

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

请参阅 live demo 从您的示例数据中找到 10


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

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

参见 live demo

这假设所有列表都不为空并且地图本身也不为空。


还有一种使用 Collections.max(), but produces an Optional` 的方式,恕我直言

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

参见 live demo

I want to find the maximum value for each map entry and inturn find minimum of those maximum values.

那么IntSummaryStatistics就是你的新朋友了。此 object 旨在提供 minmax 值、消耗的元素数量、 平均值等信息 和他们的总数。

作为结果的容器,我们可以使用映射 Map<String, IntSummaryStatistics>,它将保存映射到该值键的每个值的 统计信息。为此,我们需要收藏家 flatMapping()summarizingInt().

的帮助

然后为了得到最小最大值,我们应该处理这个map.

的值
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

一个link到Online Demo

您可以使用方法Collections.min and Collections.max

HashMap<String, List<Integer>> myMap = new HashMap<>();

Integer min = Collections.min(myMap.values().stream().map(Collections::max).collect(Collectors.toList()));