MyTetra Share
Делитесь знаниями!
Сортировать HashMap в Java
Время создания: 29.01.2021 08:46
Раздел: INFO - Development - JAVA - Collection
Запись: wwwlir/Tetra/master/base/16118812054py0dxe020/text.html на raw.githubusercontent.com

Сортировать HashMap в Java

1. Вступление

В этом кратком руководстве мы научимся сортировать HashMap в Java .

Более конкретно, мы рассмотрим сортировку записей HashMap по их ключу или значению, используя:

  • TreeMap
  • ArrayList и Collections.sort ()
  • TreeSet
  • Используя Stream API _, _ и, наконец,
  • Использование __Guava __library

2. Использование TreeMap

Как мы знаем, ключи в TreeMap отсортированы в естественном порядке .

Это хорошее решение, когда мы хотим отсортировать пары ключ-значение по их ключу. Поэтому идея состоит в том, чтобы перенести все данные из нашего HashMap в TreeMap .

Для начала давайте определим HashMap и инициализируем его некоторыми данными:

Map<String, Employee> map = new HashMap<>();

Employee employee1 = new Employee(1L, "Mher");
map.put(employee1.getName(), employee1);
Employee employee2 = new Employee(22L, "Annie");
map.put(employee2.getName(), employee2);
Employee employee3 = new Employee(8L, "John");
map.put(employee3.getName(), employee3);
Employee employee4 = new Employee(2L, "George");
map.put(employee4.getName(), employee4);

Для класса Employee обратите внимание, что мы реализовали Comparable :

public class Employee implements Comparable<Employee> {

    private Long id;
    private String name;

   //constructor, getters, setters

   //override equals and hashCode
    @Override
    public int compareTo(Employee employee) {
        return (int)(this.id - employee.getId());
    }
}

Далее мы сохраняем записи в __TreeMap __by, используя его конструктор:

TreeMap<String, Employee> sorted = new TreeMap<>(map);

Или метод putAll для копирования данных:

TreeMap<String, Employee> sorted = new TreeMap<>();
sorted.putAll(map);

И это все! Чтобы убедиться, что записи нашей карты отсортированы по ключу, распечатаем их:

Annie=Employee{id=22, name='Annie'}
George=Employee{id=2, name='George'}
John=Employee{id=8, name='John'}
Mher=Employee{id=1, name='Mher'}

Как видим, ключи отсортированы в естественном порядке.

3. Использование ArrayList

Конечно, мы можем сортировать записи карты с помощью ArrayList . Ключевое отличие от предыдущего метода в том, что мы не поддерживаем интерфейс Map здесь .

3.1. Сортировать по ключу

Давайте загрузим набор ключей в ArrayList :

List<String> employeeByKey = new ArrayList<>(map.keySet());
Collections.sort(employeeByKey);

И вывод:

----[Annie, George, John, Mher]----

3.2. Сортировать по значению

Теперь, что если мы захотим отсортировать значения нашей карты по полю id объекта Employee ? Мы также можем использовать ArrayList для этого.

Сначала давайте скопируем значения в список:

List<Employee> employeeById = new ArrayList<>(map.values());

И после этого мы сортируем это:

Collections.sort(employeeById);

Помните, что это работает, потому что Employee реализует интерфейс Comparable . В противном случае нам потребуется определить ручной компаратор для нашего вызова Collections.sort .

Чтобы проверить результаты, мы печатаем employeeById :

----[Employee{id=1, name='Mher'},
Employee{id=2, name='George'},
Employee{id=8, name='John'},
Employee{id=22, name='Annie'}]----

Как мы видим, объекты сортируются по полю id .

4. Использование TreeSet

Если мы не хотим принимать повторяющиеся значения в нашей отсортированной коллекции, есть отличное решение с TreeSet .

Во-первых, давайте добавим несколько повторяющихся записей на нашу исходную карту:

Employee employee5 = new Employee(1L, "Mher");
map.put(employee5.getName(), employee5);
Employee employee6 = new Employee(22L, "Annie");
map.put(employee6.getName(), employee6);

4.1. Сортировать по ключу

Чтобы отсортировать карту по ключевым записям:

SortedSet<String> keySet = new TreeSet<>(map.keySet());

Давайте напечатаем keySet и посмотрим результат:

----[Annie, George, John, Mher]----

Теперь у нас есть ключи карты, отсортированные без дубликатов.

4.2. Сортировать по значению

Аналогично, для значений карты код преобразования выглядит следующим образом:

SortedSet<Employee> values = new TreeSet<>(map.values());

И результаты:

----[Employee{id=1, name='Mher'},
Employee{id=2, name='George'},
Employee{id=8, name='John'},
Employee{id=22, name='Annie'}]----

Как мы видим, в выходных данных нет дубликатов. Это работает с пользовательскими объектами, когда мы переопределяем equals и hashCode .

5. Использование лямбд и потоков

  • Начиная с Java 8, мы можем использовать Stream API и лямбда-выражения для сортировки карты ** . Все, что нам нужно, это вызвать метод sorted через __stream __pipeline карты.

5.1. Сортировать по ключу

Для сортировки по ключу мы используем __comparingByKey __comparator:

map.entrySet()
  .stream()
  .sorted(Map.Entry.<String, Employee>comparingByKey())
  .forEach(System.out::println);

Последний этап forEach выводит результаты:

Annie=Employee{id=22, name='Annie'}
George=Employee{id=2, name='George'}
John=Employee{id=8, name='John'}
Mher=Employee{id=1, name='Mher'}

По умолчанию режим сортировки возрастает.

5.2. Сортировать по значению

Конечно, мы можем сортировать и объекты Employee :

map.entrySet()
  .stream()
  .sorted(Map.Entry.comparingByValue())
  .forEach(System.out::println);

Как мы видим, приведенный выше код распечатывает карту, отсортированную по полям id объектов Employee :

Mher=Employee{id=1, name='Mher'}
George=Employee{id=2, name='George'}
John=Employee{id=8, name='John'}
Annie=Employee{id=22, name='Annie'}

Кроме того, мы можем собрать результаты в новую карту:

Map<String, Employee> result = map.entrySet()
  .stream()
  .sorted(Map.Entry.comparingByValue())
  .collect(Collectors.toMap(
    Map.Entry::getKey,
    Map.Entry::getValue,
    (oldValue, newValue) -> oldValue, LinkedHashMap::new));
  • Обратите внимание, что мы собрали наши результаты в LinkedHashMap . По умолчанию Collectors.toMap возвращает новый HashMap, но, как мы знаем, HashMap не гарантирует итерацию порядка ** _, , тогда как LinkedHashMap_ делает.

6. Использование гуавы

Наконец, библиотека, которая позволяет нам сортировать HashMap , - это Guava. Прежде чем мы начнем, было бы полезно проверить нашу статью о maps в Гуаве .

Во-первых, давайте объявим Ordering , так как мы хотим отсортировать нашу карту по полю Employee’s Id :

Ordering naturalOrdering = Ordering.natural()
  .onResultOf(Functions.forMap(map, null));

Теперь все, что нам нужно, это использовать _ImmutableSortedMap _ , чтобы проиллюстрировать результаты:

ImmutableSortedMap.copyOf(map, naturalOrdering);

И еще раз, на выходе получается карта, упорядоченная по полю id

Mher=Employee{id=1, name='Mher'}
George=Employee{id=2, name='George'}
John=Employee{id=8, name='John'}
Annie=Employee{id=22, name='Annie'}

7. Резюме

В этой статье мы рассмотрели несколько способов сортировки HashMap по ключу или по значению.

И мы внимательно рассмотрели, как мы можем сделать это, когда атрибут является пользовательским классом путем реализации Comparable .

Наконец, как всегда, код, использованный во время обсуждения, можно найти на GitHub over .

Так же в этом разделе:
 
MyTetra Share v.0.59
Яндекс индекс цитирования