Java 从平均值流出最大值

Java Stream Maximum Value From Average

我必须获取最高平均气温的国家/地区名称。

我使用以下方法获取平均温度

 this.getTemperatures()
                .stream()
                .collect(Collectors.groupingBy(Temperature::getCountry,
                        Collectors.averagingDouble(Temperature::getAverageTemperature)))

如何从此平均温度列表中获取最大或最小平均国家/地区名称?

使用

Collections.min(temperatureMap.entrySet(), Comparator.comparingInt(Map.Entry::getValue)).getValue()

Collections.max(temperatureMap.entrySet(),  Comparator.comparingInt(Map.Entry::getValue)).getValue()

我不太喜欢这个,因为很多代码是重复的,但它会起作用。在不使代码变得更糟的情况下,我无法找到避免重复的方法。

这也会将所有地图条目迭代两次,但考虑到只有 195 个国家/地区,我们正在谈论最多 195 次额外迭代(如果您对每一个都有测量),这是一个完全可以忽略不计的数量对于 CPU。

String max = countryToAvgTemp.entrySet().stream()      //stream all entries
    .max(Map.Entry.comparingByValue())                 //get the max by comparing entry value
    .map(Map.Entry::getKey)                            //grab the key   
    .orElseThrow(() -> new RuntimeException("No max")); //e.g. if the list is empty

String min = countryToAvgTemp.entrySet().stream()
    .min(Map.Entry.comparingByValue())
    .map(Map.Entry::getKey)
    .orElseThrow(() -> new RuntimeException("No min"));

如果您只想迭代一次,您可以编写自己的收集器,returns 类似于 MinMax<String>。我写了一个,但代码不是很好。最好保持简单。

如果你想获得最大或最小平均国家名称,你可以对温度列表进行排序,然后获取第一个和最后一个元素。但是你的工作不需要排序列表,这不是一个好方法,@Michael's方法很适合你。

       List<Temperature> temperatures = Arrays.asList(
                new Temperature("a",10),
                new Temperature("b",11),
                new Temperature("c",12),
                new Temperature("d",13),
                new Temperature("e",14),
                new Temperature("f",15),
                new Temperature("g",16),
                new Temperature("h",17));

        temperatures = temperatures.stream().sorted(new Comparator<Temperature>() {
            @Override
            public int compare(Temperature o1, Temperature o2) {
                return (int) (o1.getAverageTemperature() - o2.getAverageTemperature());
            }
        }).collect(Collectors.toList());

        String min = temperatures.get(0).getCountry();
        String max = temperatures.get(temperatures.size()-1).getCountry();

您可以试试 DoubleSummaryStatistics:

this.getTemperatures()
            .stream()
            .collect(Collectors.groupingBy(Temperature::getCountry,
                    Collectors.summarizingDouble(Temperature::getAverageTemperature)));

这将 return 一张地图:

Map<Country, DoubleSummaryStatistics>

因此使用 DoubleSummaryStatistics,您可以获得每个国家/地区的计数、总和、最小值、最大值、平均值