|
|||||||
Сортировать HashMap в Java
Время создания: 29.01.2021 08:46
Раздел: INFO - Development - JAVA - Collection
Запись: wwwlir/Tetra/master/base/16118812054py0dxe020/text.html на raw.githubusercontent.com
|
|||||||
|
|||||||
Сортировать HashMap в Java
В этом кратком руководстве мы научимся сортировать HashMap в Java . Более конкретно, мы рассмотрим сортировку записей HashMap по их ключу или значению, используя:
Как мы знаем, ключи в 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'}
Как видим, ключи отсортированы в естественном порядке. Конечно, мы можем сортировать записи карты с помощью ArrayList . Ключевое отличие от предыдущего метода в том, что мы не поддерживаем интерфейс Map здесь . Давайте загрузим набор ключей в ArrayList : List<String> employeeByKey = new ArrayList<>(map.keySet());
Collections.sort(employeeByKey);
И вывод: ----[Annie, George, John, Mher]----
Теперь, что если мы захотим отсортировать значения нашей карты по полю 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 . Если мы не хотим принимать повторяющиеся значения в нашей отсортированной коллекции, есть отличное решение с TreeSet . Во-первых, давайте добавим несколько повторяющихся записей на нашу исходную карту: Employee employee5 = new Employee(1L, "Mher");
map.put(employee5.getName(), employee5);
Employee employee6 = new Employee(22L, "Annie");
map.put(employee6.getName(), employee6);
Чтобы отсортировать карту по ключевым записям: SortedSet<String> keySet = new TreeSet<>(map.keySet());
Давайте напечатаем keySet и посмотрим результат: ----[Annie, George, John, Mher]----
Теперь у нас есть ключи карты, отсортированные без дубликатов. Аналогично, для значений карты код преобразования выглядит следующим образом: 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. Использование лямбд и потоков
Для сортировки по ключу мы используем __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'}
По умолчанию режим сортировки возрастает. Конечно, мы можем сортировать и объекты 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));
Наконец, библиотека, которая позволяет нам сортировать 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'}
В этой статье мы рассмотрели несколько способов сортировки HashMap по ключу или по значению. И мы внимательно рассмотрели, как мы можем сделать это, когда атрибут является пользовательским классом путем реализации Comparable . Наконец, как всегда, код, использованный во время обсуждения, можно найти на GitHub over . |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|