Нахождение наибольшего значения на карте Java

Найти наибольшее значение на карте Java

1. обзор

В этом кратком руководствеwe’ll explore various ways to find the maximum value in a Java Map. Мы также увидим, как новые функции вJava 8 упростили эту операцию.

Прежде чем мы начнем, давайте кратко рассмотрим, какobjects are compared в Java.

Обычно объекты могут выражать естественный порядок путем реализации методаcompareTo() из интерфейсаComparable. Однако через объектComparator можно использовать другой порядок, а не естественный. Мы увидим их более подробно в дальнейшем.

2. До Java 8

Давайте начнем сначала с изучения того, как мы можем найти максимальную ценность без функций Java 8.

2.1. Использование простой итерации

Используя итерацию, мы могли бы просто просмотреть все записиMap, чтобы выбрать наивысшее значение, сохранив текущее наивысшее значение в переменной:

public > V maxUsingIteration(Map map) {
    Map.Entry maxEntry = null;
    for (Map.Entry entry : map.entrySet()) {
        if (maxEntry == null || entry.getValue()
            .compareTo(maxEntry.getValue()) > 0) {
            maxEntry = entry;
        }
    }
    return maxEntry.getValue();
}

Здесь мы также используем универсальные шаблоны Java для создания метода, который можно применять к различным типам.

2.2. ИспользуяCollections.max()

Теперь давайте посмотрим, как служебный методmax() в классеCollections может избавить нас от написания многих из них самим:

public > V maxUsingCollectionsMax(Map map) {
    Entry maxEntry = Collections.max(map.entrySet(), new Comparator>() {
        public int compare(Entry e1, Entry e2) {
            return e1.getValue()
                .compareTo(e2.getValue());
        }
    });
    return maxEntry.getValue();
}

В этом примереwe’re passing a Comparator object to max(), который может использовать естественный порядок значенийEntry черезcompareTo() или вообще реализовать другой порядок.

3. После Java 8

Возможности Java 8 могут упростить нашу попытку получить максимальное значение изMapнесколькими способами, чем один.

3.1. ИспользованиеCollections.max() с лямбда-выражением

Начнем с изучения того, как лямбда-выражения могут упростить вызовCollections.max():

public > V maxUsingCollectionsMaxAndLambda(Map map) {
    Entry maxEntry = Collections.max(map.entrySet(), (Entry e1, Entry e2) -> e1.getValue()
        .compareTo(e2.getValue()));
    return maxEntry.getValue();
}

Как мы видим здесь,lambda expressions save us from defining the full-fledged functional interface - это краткий способ определения логики. Чтобы узнать больше о лямбда-выражениях, также посмотритеour previous article.

3.2. ИспользуяStream

APIStream - еще одно дополнение кJava 8, которое значительно упростило работу с коллекциями:

public > V maxUsingStreamAndLambda(Map map) {
    Optional> maxEntry = map.entrySet()
        .stream()
        .max((Entry e1, Entry e2) -> e1.getValue()
            .compareTo(e2.getValue())
        );

    return maxEntry.get().getValue();
}

Этот API предлагает множество запросов на обработку данных, таких как преобразованияmap-reduce в коллекциях. Here, we’ve used max() over a stream of Map Entry, который является частным случаем операции сокращения. Более подробная информация об APIStream доступнаhere.

Мы также используем APIOptional, который представляет собой контейнерный объект, добавленный в Java 8, который может содержать или не содержать ненулевое значение. Более подробную информацию оOptional можно получитьhere.

3.3. ИспользованиеStream со ссылкой на метод

Наконец, давайте посмотрим, как ссылки на методы могут еще больше упростить использование лямбда-выражений:

public > V maxUsingStreamAndMethodReference(Map map) {
    Optional> maxEntry = map.entrySet()
        .stream()
        .max(Comparator.comparing(Map.Entry::getValue));
    return maxEntry.get()
        .getValue();
}

В случаях, когда лямбда-выражения просто вызывают существующий метод, ссылка на метод позволяет нам сделать это, используя имя метода напрямую. Для получения более подробной информации о method references посмотритеthis previous article.

4. Заключение

В этой статье мы рассмотрели несколько способов нахождения максимального значения вJava Map, некоторые из которых использовали функции, добавленные как часть Java 8.

Как всегда, доступен код для примеровover on GitHub.