如何对Java HashMap进行排序
时间:2020-01-09 10:35:04 来源:igfitidea点击:
Java中的HashMap根据插入的(键,值)对的键计算哈希,并根据该键存储其元素。因此,HashMap本质上是一个无序的集合,但是当我们想用Java对HashMap进行排序时,我们可能会遇到一种情况。
HashMap的排序既可以按键也可以按值进行,在本文中,我们将介绍基于Java键或者值对HashMap进行排序的方法。
在键上对HashMap排序
如果必须对Java中的键对HashMap进行排序,最简单的选择是将HashMap转换为TreeMap。
TreeMap根据其键的自然顺序或者在创建地图时提供的Comparator进行排序,具体取决于所使用的构造函数。如果要根据其键的自然顺序对HashMap进行排序,则可以使用TreeMap类的以下构造函数。
TreeMap(Map <?扩展K ,?扩展V> m)–构造一个新的树图,该树图包含与给定图相同的映射,并根据其键的自然顺序进行排序。
import java.util.HashMap; import java.util.Map; import java.util.TreeMap; public class SortMap { public static void main(String[] args) { // Creating HashMap Map<String, String> empMap = new HashMap<String, String>(); // Storing elements empMap.put("E01", "Hyman"); empMap.put("E02", "Amy"); empMap.put("E11", "Harvey"); empMap.put("E45", "Mike"); System.out.println("** Unsorted Map **"); for(Map.Entry<String, String> emp : empMap.entrySet()) { System.out.println("Key- " + emp.getKey() + " Value- " + emp.getValue()); } TreeMap<String, String> sortedEmpMap = new TreeMap<>(empMap); System.out.println("** Map sorted by keys **"); for(Map.Entry<String, String> emp : sortedEmpMap.entrySet()) { System.out.println("Key- " + emp.getKey() + " Value- " + emp.getValue()); } } }
输出:
** Unsorted Map ** Key- E11 Value- Harvey Key- E02 Value- Amy Key- E01 Value- Hyman Key- E45 Value- Mike ** Map sorted by keys ** Key- E01 Value- Hyman Key- E02 Value- Amy Key- E11 Value- Harvey Key- E45 Value- Mike
按值对HashMap排序
为了对值上的Java HashMap进行排序,我们必须将HashMap转换为Set,然后对该Set进行排序。为了对Set进行排序,我们再次有两个选项将该Set转换为List或者TreeSet。
如果只希望按排序顺序排列Map的值,那么将Map的值转换为TreeSet是最简单的选择。
public class SortMap { public static void main(String[] args) { // Creating HashMap Map<String, String> empMap = new HashMap<String, String>(); // Storing elements empMap.put("E01", "Hyman"); empMap.put("E02", "Amy"); empMap.put("E11", "Harvey"); empMap.put("E45", "Mike"); System.out.println("** Unsorted Map **"); for(Map.Entry<String, String> emp : empMap.entrySet()) { System.out.println("Key- " + emp.getKey() + " Value- " + emp.getValue()); } // Creating a TreeSet Set<String> empSet = new TreeSet<String>(empMap.values()); System.out.println("** Sorted Set **"); for(String emp : empSet) { System.out.println(" Value- " + emp); } } }
输出:
** Unsorted Map ** Key- E11 Value- Harvey Key- E02 Value- Amy Key- E01 Value- Hyman Key- E45 Value- Mike ** Sorted Set ** Value- Amy Value- Harvey Value- Hyman Value- Mike
如我们所见,对值进行了排序,唯一的缺点是现在有了Set而不是Map,因为现在只存储了值。
如果希望使用Map作为对Java中的HashMap进行排序的最终结果,则该过程会有些冗长。
- 创建一个指定比较器进行排序的TreeSet。
- 通过使用addAll()方法将HashMap的条目集转换为TreeSet。在这一步,我们有一个包含Map.entry元素的排序集。
- 创建一个LinkedHashMap来存储排序后的值。在这里使用LinkedHashMap是因为它维护插入顺序。
- 迭代TreeSet并将值放入创建的LinkedHashMap中。
import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import java.util.TreeSet; public class SortMap { public static void main(String[] args) { // Creating HashMap Map<String, String> empMap = new HashMap<String, String>(); // Storing elements empMap.put("E01", "Hyman"); empMap.put("E02", "Amy"); empMap.put("E11", "Harvey"); empMap.put("E45", "Mike"); System.out.println("** Unsorted Map **"); for(Map.Entry<String, String> emp : empMap.entrySet()) { System.out.println("Key- " + emp.getKey() + " Value- " + emp.getValue()); } // Creating a treeset with comparator Set<Map.Entry<String, String>> empSet = new TreeSet<Map.Entry<String, String>>(new EmpComparator()); // Adding the entry set to a TreeSet empSet.addAll(empMap.entrySet()); System.out.println("** Sorted Set **"); for(Map.Entry<String, String> emp : empSet) { System.out.println("Key- " + emp.getKey() + " Value- " + emp.getValue()); } // Using LinkedHashMap to maintain insertion order Map<String, String> sortedEmpMap = new LinkedHashMap<>(); // Insert values in LinkedHashMap for(Map.Entry<String, String> emp : empSet) { sortedEmpMap.put(emp.getKey(), emp.getValue()); } System.out.println("** Map Sorted by Values **"); for(Map.Entry<String, String> emp : sortedEmpMap.entrySet()) { System.out.println("Key- " + emp.getKey() + " Value- " + emp.getValue()); } } } // Comparator class class EmpComparator implements Comparator<Map.Entry<String, String>>{ @Override public int compare(Map.Entry<String, String> entry1, Map.Entry<String, String> entry2) { return entry1.getValue().compareTo(entry2.getValue()); } }
输出:
** Unsorted Map ** Key- E11 Value- Harvey Key- E02 Value- Amy Key- E01 Value- Hyman Key- E45 Value- Mike ** Sorted Set ** Key- E02 Value- Amy Key- E11 Value- Harvey Key- E01 Value- Hyman Key- E45 Value- Mike ** Map Sorted by Values ** Key- E02 Value- Amy Key- E11 Value- Harvey Key- E01 Value- Hyman Key- E45 Value- Mike
除了TreeSet,还可以使用ArrayList来存储Map.Entry元素。在这种情况下,我们可以使用Collections.sort(list,new EmpComparator())对值进行排序。