Сортирайте HashMap в Java

1. Въведение

В този бърз урок ще научим как да сортирате HashMap в Java .

По-конкретно, ще разгледаме сортирането на записите в HashMap по техния ключ или стойност, като използваме:

  • TreeMap
  • ArrayList и Collections.sort ()
  • TreeSet
  • Използване на живо API , и най-накрая,
  • Използване на библиотеката Guava

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

Както знаем, ключовете в TreeMap са сортирани по естествения им ред . Това е добро решение, когато искаме да сортираме двойките ключ-стойност по техния ключ. Идеята е да се изтласкат всички данни от нашата HashMap в TreeMap .

Като начало, нека дефинираме HashMap и го инициализираме с някои данни:

Map 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 { 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, като използваме неговия конструктор:

TreeMap sorted = new TreeMap(map);

Или методът putAll за копиране на данните:

TreeMap 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 employeeByKey = new ArrayList(map.keySet()); Collections.sort(employeeByKey);

И изходът е:

[Annie, George, John, Mher]

3.2. Сортирай по стойност

Ами сега, ако искаме да сортираме нашите картографски стойности по полето id на обекта на служител ? Можем да използваме ArrayList и за това.

Първо, нека копираме стойностите в списъка:

List employeeById = new ArrayList(map.values());

И след това го сортираме:

Collections.sort(employeeById);

Не забравяйте, че това работи, защото Служителят прилага Сравним интерфейс . В противен случай ще трябва да дефинираме ръчен компаратор за извикването ни към Collections.sort .

За да проверим резултатите, отпечатваме workerById :

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

Както виждаме, обектите са сортирани по тяхното поле за идентификация .

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 keySet = new TreeSet(map.keySet());

Нека отпечатаме keySet и да видим резултата:

[Annie, George, John, Mher]

Сега имаме сортирани ключове на картата без дубликатите.

4.2. Сортирай по стойност

По същия начин за стойностите на картата кодът за преобразуване изглежда така:

SortedSet 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. Използване на Lambdas и Streams

Тъй като Java 8, можем да използваме Stream API и ламбда изрази, за да сортираме картата . Всичко, от което се нуждаем, е да извикаме сортирания метод през поточния конвейер на картата .

5.1. Сортирай по ключ

За сортиране по ключ използваме сравнителния сравнителенByKey:

map.entrySet() .stream() .sorted(Map.Entry.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. Сортирай по стойност

Разбира се, можем да сортираме и по обектите на служителите :

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

As we see, the code above prints out a map sorted by the id fields of Employee objects:

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

Additionally, we can collect the results into a new map:

Map result = map.entrySet() .stream() .sorted(Map.Entry.comparingByValue()) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new));

Note that we collected our results into a LinkedHashMap. By default, Collectors.toMap returns a new HashMap, but as we know, HashMap doesn't guarantee iterationorder, while LinkedHashMap does.

6. Using Guava

Lastly, a library that allows us to sort the HashMap is Guava. Before we start, it'll be useful to check our write-up about maps in Guava.

Първо, нека декларираме Поръчка, тъй като искаме да сортираме картата си по полето 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.