Максимальное значение потока Java от среднего

Мне нужно получить название страны для максимальной средней температуры.

Я использовал следующие, чтобы получить средние температуры

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

Как я могу получить максимальное или минимальное среднее название страны из этого списка средних температур?

что вы имеете в виду под максимальным средним значением? пример ?

Schidu Luca 10.01.2019 12:53

Есть название класса IntSummaryStatistics, пробовали?

Vishwa Ratna 10.01.2019 12:54

@SchiduLuca У меня есть список средних температур, сгруппированных по странам. Теперь я хочу получить страну с максимальным значением из этого списка с помощью потоков.

user2578909 10.01.2019 13:01
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
3
193
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Использовать

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

и

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

Это несопоставимые Map.Entry.

Michael 10.01.2019 12:57
Ответ принят как подходящий

Мне это не очень нравится, потому что большая часть кода повторяется, но это сработает. Я не могу найти способ избежать повторения без ухудшения кода.

Это также повторяет все записи карты дважды, но, учитывая, что есть только 195 стран, мы говорим о максимум 195 дополнительных итерациях (если у вас есть измерения для каждой из них), а это совершенно незначительное количество для ЦП.

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

Если вы хотите выполнить итерацию только один раз, вы можете написать свой собственный сборщик, который возвращает что-то вроде MinMax<String>. Я написал один, но код был не лучшим. Лучше, чтобы это было проще.

.max(Comparator.comparing(Map.Entry::getValue)) -> `.max(Map.Entry.comparingByValue())
Ousmane D. 10.01.2019 14:06

@Aomine Спасибо. Я удивлен, что IntelliJ не предупредил меня об этом. Обычно это неплохо для таких вещей.

Michael 10.01.2019 15:21

Или за один проход, используя SummaryStatistics из этот ответ: SummaryStatistics<Map.Entry<String,Double>> s = countryToAvgTemp.entrySet().stream() .collect(SummaryStatistics.statistics(Map.Entry.comparingByV‌​alue())); String min = s.getMin().getKey(), max = s.getMax().getKey();

Holger 10.01.2019 15:28

@Holger Конечно, но я бы не рекомендовал брать весь класс из Stack Overflow без каких-либо тестов или чего-то еще.

Michael 10.01.2019 15:35

Что ж, многие люди используют целые библиотеки классов без каких-либо тестов просто потому, что это библиотека с именем. Я могу утверждать, что у меня есть тесты для этого класса в моей кодовой базе, и любому разработчику не так уж сложно написать тесты для него. В конце концов, реализуя его самостоятельно, вместо того, чтобы брать его из Stackoverflow, им пришлось писать те же тесты.

Holger 10.01.2019 15:45

Если вы хотите получить максимальное или минимальное среднее название страны ,, вы можете отсортировать список температур, а затем получить первый и последний элемент Но ваша работа не требует отсортированного списка , это не лучший метод , Метод @ Michael очень хорош для ты.

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

это вернет карту:

Map<Country, DoubleSummaryStatistics>

Таким образом, с помощью DoubleSummaryStatistics вы можете получить количество, сумму, минимум, максимум, среднее значение для каждой страны.

Другие вопросы по теме