1. Обзор
В этом кратком руководстве мы рассмотрим различные способы поиска максимального значения в Java Map . Мы также увидим, как новые функции в Java 8 упростили эту операцию.
Прежде чем мы начнем, давайте кратко расскажем, как сравниваются объекты в 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. Использование коллекций.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(); }
В этом примере мы передаем объект Comparator в 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(); }
Как мы видим здесь, лямбда-выражения избавляют нас от определения полноценного функционального интерфейса и обеспечивают краткий способ определения логики. Чтобы узнать больше о лямбда-выражениях, также ознакомьтесь с нашей предыдущей статьей .
3.2. Использование потока
API Stream является еще одним дополнением к 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 преобразования в коллекциях. Здесь мы использовали max() над потоком Записи карты , что является частным случаем операции сокращения. Более подробная информация о Stream API доступна здесь .
Мы также используем здесь Необязательный API, который представляет собой объект-контейнер, добавленный в Java 8, который может содержать или не содержать ненулевое значение. Более подробную информацию о Необязательно можно получить здесь .
3.3. Использование потока со ссылкой на метод
Наконец, давайте посмотрим, как ссылки на методы могут еще больше упростить использование лямбда-выражений:
public> V maxUsingStreamAndMethodReference(Map map) { Optional > maxEntry = map.entrySet() .stream() .max(Comparator.comparing(Map.Entry::getValue)); return maxEntry.get() .getValue(); }
В тех случаях, когда лямбда-выражения просто вызывают существующий метод, ссылка на метод позволяет нам сделать это, используя имя метода напрямую. Для получения более подробной информации о ссылках m ethod взгляните на эту предыдущую статью .
4. Заключение
В этой статье мы рассмотрели несколько способов найти наибольшее значение в Java Map , некоторые из которых использовали функции , добавленные в Java 8.
Как всегда, код для примеров доступен на GitHub .