Сортировать HashMap в Java
В этом кратком руководстве мы узнаем, какsort a HashMap in Java.
В частности, мы рассмотрим сортировку записейHashMap по их ключу или значению, используя:
- TreeMap
- ArrayList иCollections.sort()
- TreeSet
- ИспользуяStream API, и, наконец,
- Используя списокGuava
2. ИспользуяTreeMap
Как известно,keys in TreeMap are sorted using their natural order. Это хорошее решение, когда мы хотим отсортировать пары ключ-значение по их ключу. Идея состоит в том, чтобы поместить все данные из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);
Для классаEmployeenote that we’ve implemented 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 by, используя его конструктор:
TreeMap sorted = new TreeMap<>(map);
Или методputAll для копирования данных:
TreeMap sorted = new TreeMap<>(); sorted.putAll(map);
Вот и все! Чтобы убедиться, что записи на карте отсортированы по ключам, распечатаем их:
Annie=Employee George=Employee John=Employee Mher=Employee
Как видим, ключи отсортированы в естественном порядке.
3. ИспользуяArrayList
Конечно, мы можем отсортировать записи карты с помощьюArrayList. Ключевое отличие от предыдущего метода в том, чтоwe don’t maintain the Map interface here.
3.1. Сортировать по ключу
Загрузим набор ключей вArrayList:
List employeeByKey = new ArrayList<>(map.keySet()); Collections.sort(employeeByKey);
How to Sort a HashMap by Value in Java?
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
HashMap in java provides quick lookups. They store items in “key, value” pairs. To get a value from the HashMap, we use the key corresponding to that entry. HashMaps are a good method for implementing Dictionaries and directories. Key and Value can be of different types (eg — String, Integer). We can sort the entries in a HashMap according to keys as well as values. In this tutorial we will sort the HashMap according to value. The basic strategy is to get the values from the HashMap in a list and sort the list. Here if the data type of Value is String, then we sort the list using a comparator. To learn more about comparator, read this tutorial. Once we have the list of values in a sorted manner, we build the HashMap again based on this new list. Let’s look at the code.
Sorting HashMap by Value Simple Example
We first get the String values in a list. Then we sort the list. To sort the String values in the list we use a comparator. This comparator sorts the list of values alphabetically.
Collections.sort(list, new ComparatorString>() public int compare(String str, String str1) return (str).compareTo(str1); > >);
Once, we have sorted the list, we build the HashMap based on this sorted list. The complete code is as follows :
package com.journaldev.collections; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; public class Main public static void main(String[] args) HashMapString, String> map = new HashMap>(); LinkedHashMapString, String> sortedMap = new LinkedHashMap>(); ArrayListString> list = new ArrayList>(); map.put("2", "B"); map.put("8", "A"); map.put("4", "D"); map.put("7", "F"); map.put("6", "W"); map.put("19", "J"); map.put("1", "Z"); for (Map.EntryString, String> entry : map.entrySet()) list.add(entry.getValue()); > Collections.sort(list, new ComparatorString>() public int compare(String str, String str1) return (str).compareTo(str1); > >); for (String str : list) for (EntryString, String> entry : map.entrySet()) if (entry.getValue().equals(str)) sortedMap.put(entry.getKey(), str); > > > System.out.println(sortedMap); > >
HashMap entries are sorted according to String value.
Another Example of Sorting HashMap by Value
package com.JournalDev; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; public class Main public static void main(String[] args) HashMapString, Integer> map = new HashMap>(); LinkedHashMapString, Integer> sortedMap = new LinkedHashMap>(); ArrayListInteger> list = new ArrayList>(); map.put("A", 5); map.put("B", 7); map.put("C", 3); map.put("D", 1); map.put("E", 2); map.put("F", 8); map.put("G", 4); for (Map.EntryString, Integer> entry : map.entrySet()) list.add(entry.getValue()); > Collections.sort(list); for (int num : list) for (EntryString, Integer> entry : map.entrySet()) if (entry.getValue().equals(num)) sortedMap.put(entry.getKey(), num); > > > System.out.println(sortedMap); > >
Here HashMap values are sorted according to Integer values.
Sorting the HashMap using a custom comparator
If you notice the above examples, the Value objects implement the Comparator interface. Let’s look at an example where our value is a custom object. We can also create a custom comparator to sort the hash map according to values. This is useful when your value is a custom object. Let’s take an example where value is a class called ‘Name’. This class has two parameters, firstName and lastName. The code for class Name is :
package com.JournalDev; public class Name String firstName; String lastName; Name(String a, String b) firstName=a; lastName=b; > public String getFirstName() return firstName; > >
ComparatorName> byName = (Name obj1, Name obj2) -> obj1.getFirstName().compareTo(obj2.getFirstName());
We are sorting the names according to firstName, we can also use lastName to sort. Rather than using a list to get values from the map, we’ll be using LinkedHashMap to create the sorted hashmap directly. The complete code is :
public static void main(String[] args) HashMapInteger, Name> hmap = new HashMapInteger, Name>(); Name name1 = new Name("Jayant", "Verma"); Name name2 = new Name("Ajay", "Gupta"); Name name3 = new Name("Mohan", "Sharma"); Name name4 = new Name("Rahul", "Dev"); hmap.put(9, name1); hmap.put(1, name2); hmap.put(6, name3); hmap.put(55, name4); ComparatorName> byName = (Name obj1, Name obj2) -> obj1.getFirstName().compareTo(obj2.getFirstName()); LinkedHashMapInteger, Name> sortedMap = hmap.entrySet().stream() .sorted(Map.Entry.Integer, Name>comparingByValue(byName)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); //printing the sorted hashmap Set set = sortedMap.entrySet(); Iterator iterator = set.iterator(); while (iterator.hasNext()) Map.Entry me2 = (Map.Entry) iterator.next(); System.out.print(me2.getKey() + ": "); System.out.println(hmap.get(me2.getKey()).firstName + " "+hmap.get(me2.getKey()).lastName ); > >
1: Ajay Gupta 9: Jayant Verma 6: Mohan Sharma 55: Rahul Dev
Conclusion
This tutorial covered sorting of HashMap according to Value. Sorting for String values differs from Integer values. String values require a comparator for sorting. Whereas, Integer values are directly sorted using Collection.sort().
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases. Learn more about us
Interface SortedMap
Type Parameters: K — the type of keys maintained by this map V — the type of mapped values All Superinterfaces: Map All Known Subinterfaces: ConcurrentNavigableMap , NavigableMap All Known Implementing Classes: ConcurrentSkipListMap , TreeMap
A Map that further provides a total ordering on its keys. The map is ordered according to the natural ordering of its keys, or by a Comparator typically provided at sorted map creation time. This order is reflected when iterating over the sorted map’s collection views (returned by the entrySet , keySet and values methods). Several additional operations are provided to take advantage of the ordering. (This interface is the map analogue of SortedSet .)
All keys inserted into a sorted map must implement the Comparable interface (or be accepted by the specified comparator). Furthermore, all such keys must be mutually comparable: k1.compareTo(k2) (or comparator.compare(k1, k2) ) must not throw a ClassCastException for any keys k1 and k2 in the sorted map. Attempts to violate this restriction will cause the offending method or constructor invocation to throw a ClassCastException .
Note that the ordering maintained by a sorted map (whether or not an explicit comparator is provided) must be consistent with equals if the sorted map is to correctly implement the Map interface. (See the Comparable interface or Comparator interface for a precise definition of consistent with equals.) This is so because the Map interface is defined in terms of the equals operation, but a sorted map performs all key comparisons using its compareTo (or compare ) method, so two keys that are deemed equal by this method are, from the standpoint of the sorted map, equal. The behavior of a tree map is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the Map interface.
- A void (no arguments) constructor, which creates an empty sorted map sorted according to the natural ordering of its keys.
- A constructor with a single argument of type Comparator , which creates an empty sorted map sorted according to the specified comparator.
- A constructor with a single argument of type Map , which creates a new map with the same key-value mappings as its argument, sorted according to the keys’ natural ordering.
- A constructor with a single argument of type SortedMap , which creates a new sorted map with the same key-value mappings and the same ordering as the input sorted map.
Note: several methods return submaps with restricted key ranges. Such ranges are half-open, that is, they include their low endpoint but not their high endpoint (where applicable). If you need a closed range (which includes both endpoints), and the key type allows for calculation of the successor of a given key, merely request the subrange from lowEndpoint to successor(highEndpoint) . For example, suppose that m is a map whose keys are strings. The following idiom obtains a view containing all of the key-value mappings in m whose keys are between low and high , inclusive:
SortedMap sub = m.subMap(low, high+"\0");
A similar technique can be used to generate an open range (which contains neither endpoint). The following idiom obtains a view containing all of the key-value mappings in m whose keys are between low and high , exclusive:
SortedMap sub = m.subMap(low+"\0", high);
This interface is a member of the Java Collections Framework.
Sort a Map by Values in Java
Simple and easy-to-understand examples of sorting Map by values, using Java 8 Stream APIs, in ascending and descending (reverse) orders. At the center of logic is the method Map.Entry.comparingByValue(), which compares the map entries in the natural order by entry values.
In Java 8, Map.Entry class has a static method comparingByValue() to help sort a Map by values. It returns a Comparator that compares Map.Entry in the natural order of values.
map.entrySet() .stream() .sorted(Map.Entry.comparingByValue()) .
Alternatively, we can pass a custom Comparator to sort the values in a custom order. For example, we can use Comparator.reverseOrder() to sort the map in reverse order.
map.entrySet() .stream() .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) .
2. Java Program to Sort a Map by Values
2.1. Ascending Order or Natural Order
The following java program sorts the entries of a Map in the natural order and collects the sorted entries in a LinkedHashMap. We are collecting the entries in LinkedHashMap because it maintains the insertion order.
Map unsortedMap = Map.of("a", 1, "c", 3, "b", 2, "e", 5, "d", 4); LinkedHashMap sortedMap = unsortedMap.entrySet() .stream() .sorted(Map.Entry.comparingByValue()) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new)); System.out.println(sortedMap);
As discussed above, we use Comparator.reverseOrder() to sorting the Map values in reverse order.
Map unsortedMap = Map.of("a", 1, "c", 3, "b", 2, "e", 5, "d", 4); LinkedHashMap sortedMap = unsortedMap.entrySet() .stream() .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new)); System.out.println(sortedMap);