Автор оригинала: David Landup.
В этом уроке мы рассмотрим как сортировать хэш-карту по значению в Java .
Давайте продолжим и создадим простую Хэш-карту
:
MapunsortedMap = new HashMap(); unsortedMap.put("John", 21); unsortedMap.put("Maria", 34); unsortedMap.put("Mark", 31); unsortedMap.put("Sydney", 24); unsortedMap.entrySet().forEach(System.out::println);
У нас есть Строка
s в качестве ключей и Целое число
s в качестве значений. И мы хотели бы отсортировать эту карту на основе значений.
HashMap
s не гарантирует сохранение порядка его элементов в любом случае. Порядок может меняться со временем, и наиболее определенно не будет напечатан обратно в порядке вставки:
John=21 Mark=31 Maria=34 Sydney=24
Если вы повторно запустите эту программу, она сохранит этот порядок, так как HashMap
упорядочивает свои элементы в ячейки на основе хэш-значения ключей. При печати значений из HashMap
его содержимое печатается последовательно , поэтому результаты останутся прежними, если мы повторно запустим программу несколько раз.
Примечание: |/Карта деревьев расширяет интерфейс
SortedMap , в отличие от реализации
HashMap .
Древовидная карта s
означает быть отсортированным аналогом, однако Древовидная карта s
только сортируется по ключам , учитывая компаратор.
Сортировка хэш-карты по значению с помощью LinkedHashMap
LinkedHashMap
сохраняет порядок вставки. Он содержит двусвязный список всех записей, что позволяет вам очень естественно получать доступ к его элементам и перебирать их.
Итак, самый простой способ преобразовать несортированную Хэш-карту
в связанную хэш-карту
– это добавить элементы в том порядке, в котором мы хотели бы их видеть.
Сортировка хэш-карты в порядке возрастания
Чтобы отсортировать несортированную карту
, которую мы видели ранее, мы создадим новую Связанную карту
для размещения элементов в том порядке, в котором мы хотим, чтобы они находились.
Давайте начнем с сортировки Хэш-карты
в порядке возрастания:
MapsortedMap = unsortedMap.entrySet().stream() .sorted(Comparator.comparingInt(e -> e.getValue())) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (a, b) -> { throw new AssertionError(); }, LinkedHashMap::new )); sortedMap.entrySet().forEach(System.out::println);
То, что мы здесь сделали, – это потоковое | Несортированное изображение набор объектов
Map.Entry . Затем, используя метод
sorted () , мы можем использовать различные
Компараторы , чтобы указать, как сравниваются записи.
Поскольку мы имеем дело с простыми целыми числами, мы можем легко использовать метод Comparator.comparingInt()
и передать Лямбда-выражение . С помощью этого выражения мы задаем сортировку ключ из типа T
(в нашем случае Целое число
).Затем этот метод возвращает Компаратор
, который сравнивает этот ключ сортировки.
Как только они отсортированы, мы можем собрать()
их в новую карту с помощью вызова Collectors.toMap ()
, где мы используем те же Map.Entry::getKey
и Map.Entry::GetValue
, как в Несортированной карте
.
Наконец, создается новый LinkedHashMap
, в который вставляются все эти элементы в отсортированном порядке.
Выполнение этого кода приводит к:
John=21 Sydney=24 Mark=31 Maria=34
В качестве альтернативы вместо Comparator.comparingInt ()
вы можете использовать Map.Entry.comparingByValue()
:
MapsortedMap = unsortedMap.entrySet().stream() .sorted(Map.Entry.comparingByValue()) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (a, b) -> { throw new AssertionError(); }, LinkedHashMap::new )); sortedMap.entrySet().forEach(System.out::println);
Однако при таком подходе вы не можете указать свою собственную логику для сравнений. Сопоставимые значения, такие как целые числа, сортируются с помощью скрытой реализации. Однако вы можете указать пользовательский объект и указать свою собственную логику сравнения в этом классе.
В очень похожем ключе вы также можете просто использовать Map.Entry::GetValue
:
MapsortedMap = unsortedMap.entrySet().stream() .sorted(Comparator.comparingInt(Map.Entry::getValue)) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (a, b) -> { throw new AssertionError(); }, LinkedHashMap::new )); sortedMap.entrySet().forEach(System.out::println);
Это также возвращает:
John=21 Sydney=24 Mark=31 Maria=34
Этот метод функционально точно такой же, как и предыдущий, так как Map.Entry.comparingByValue()
использует метод GetValue()
для сравнения записей в любом случае.
Сортировка хэш-карты в порядке Убывания
Git Essentials
Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!
Теперь давайте вместо этого отсортируем несортированную хэш-карту
в порядке убывания . Единственное различие, которое вам нужно сделать, – это Лямбда-выражение, которое мы предоставили методу Comparator.comparingInt ()
– вместо этого мы просто будем использовать - e.GetValue()
:
MapsortedMap = unsortedMap.entrySet().stream() .sorted(Comparator.comparingInt(e -> -e.getValue())) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (a, b) -> { throw new AssertionError(); }, LinkedHashMap::new )); sortedMap.entrySet().forEach(System.out::println);
Это приводит к:
Maria=34 Mark=31 Sydney=24 John=21
Это дополнительное преимущество использования этого подхода вместо Map.Entry.comparingByValue()
или Map.Entry::GetValue
. Вы можете легко переключаться между порядком убывания и возрастания.
Вывод
В этом уроке мы рассмотрели, как отсортировать хэш-карту Java по значению . Мы использовали потоки Java 8 с классом LinkedHashMap
для достижения этой функциональности, как для сортировки по возрастанию, так и по убыванию значений.