1. введение
В этом кратком руководстве мы узнаем, как сортировать HashMap в Java .
Более конкретно, мы рассмотрим сортировку записей HashMap по их ключу или значению с помощью:
- Древовидная карта
- ArrayList и Collections.sort()
- Набор деревьев
- Использование Stream API , и, наконец,,
- Использование библиотеки Guava
2. Использование древовидной карты
Как мы знаем, ключи в TreeMap сортируются в их естественном порядке . Это хорошее решение, когда мы хотим отсортировать пары ключ-значение по их ключу. Таким образом, идея состоит в том, чтобы поместить все данные из нашей HashMap в TreeMap .
Для начала давайте определим HashMap и инициализируем его некоторыми данными:
Mapmap = 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{ 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 с помощью его конструктора:
TreeMapsorted = new TreeMap<>(map);
Или метод putAll для копирования данных:
TreeMapsorted = 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 :
ListemployeeByKey = new ArrayList<>(map.keySet()); Collections.sort(employeeByKey);
И выход есть:
[Annie, George, John, Mher]
3.2. Сортировка по значению
Теперь, что если мы хотим отсортировать наши значения карты по полю id объекта Employee ? Для этого мы также можем использовать ArrayList .
Во – первых, давайте скопируем значения в список:
ListemployeeById = new ArrayList<>(map.values());
И после этого мы его сортируем:
Collections.sort(employeeById);
Помните, что это работает, потому что Employee реализует Comparable interface . В противном случае нам нужно было бы определить ручной компаратор для нашего вызова Collections.сортировка .
Чтобы проверить результаты, мы печатаем employee By Id :
[Employee{id=1, name='Mher'}, Employee{id=2, name='George'}, Employee{id=8, name='John'}, Employee{id=22, name='Annie'}]
Как мы видим, объекты сортируются по их полю id .
4. Использование набора деревьев
В случае, если мы не хотим принимать повторяющиеся значения в нашей отсортированной коллекции, есть хорошее решение с 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. Сортировка по ключу
Сортировка карты по ключевым элементам:
SortedSetkeySet = new TreeSet<>(map.keySet());
Давайте напечатаем набор ключей и посмотрим на результат:
[Annie, George, John, Mher]
Теперь у нас есть ключи карты, отсортированные без дубликатов.
4.2. Сортировка по значению
Аналогично, для значений карты код преобразования выглядит следующим образом:
SortedSetvalues = 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 карты.
5.1. Сортировка по ключу
Для сортировки по ключу мы используем компаратор comparingByKey comparator:
map.entrySet() .stream() .sorted(Map.Entry.comparingByKey()) .forEach(System.out::println);
Итоговый для каждого этапа выводит результаты:
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'}
Кроме того, мы можем собрать результаты в новую карту:
Mapresult = 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 не гарантирует итерацию | order , while LinkedHashMap делает.
6. Использование Гуавы
Наконец, библиотека, которая позволяет нам сортировать HashMap , – это Guava. Прежде чем мы начнем, будет полезно проверить ваши записи о картах в Гуаве .
Во-первых, давайте объявим 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 .