Рубрики
Без рубрики

Как отсортировать хэш-карту по значению в Java

В этом уроке мы рассмотрим, как сортировать хэш-карту по значению в Java. Мы будем использовать потоки Java 8 и класс LinkedHashMap для сортировки в порядке возрастания и убывания.

Автор оригинала: David Landup.

В этом уроке мы рассмотрим как сортировать хэш-карту по значению в Java .

Давайте продолжим и создадим простую Хэш-карту :

Map unsortedMap = 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 сохраняет порядок вставки. Он содержит двусвязный список всех записей, что позволяет вам очень естественно получать доступ к его элементам и перебирать их.

Итак, самый простой способ преобразовать несортированную Хэш-карту в связанную хэш-карту – это добавить элементы в том порядке, в котором мы хотели бы их видеть.

Сортировка хэш-карты в порядке возрастания

Чтобы отсортировать несортированную карту , которую мы видели ранее, мы создадим новую Связанную карту для размещения элементов в том порядке, в котором мы хотим, чтобы они находились.

Давайте начнем с сортировки Хэш-карты в порядке возрастания:

Map sortedMap = 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() :

Map sortedMap = 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 :

Map sortedMap = 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() :

Map sortedMap = 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 для достижения этой функциональности, как для сортировки по возрастанию, так и по убыванию значений.