用Java對HashMap排序

1.簡介

在本快速教程中,我們將學習如何在Java中對HashMap**進行排序**。

更具體地說,我們將研究使用以下項按鍵或值對HashMap條目進行排序:

  • TreeMap
  • ArrayListCollections.sort()
  • TreeSet
  • 使用Stream API ,最後,
  • 使用Guava

2.使用TreeMap

眾所周知, 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

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'}

如我們所見,鍵是按自然順序排序的。

3.使用**ArrayList**

當然,我們可以藉助ArrayList對地圖的條目進行排序。與以前的方法的主要區別是我們在這裡不維護Map接口

3.1。按鍵排序

讓我們將密鑰集加載到ArrayList

List<String> employeeByKey = new ArrayList<>(map.keySet());

 Collections.sort(employeeByKey);

輸出為:

[Annie, George, John, Mher]

3.2。按值排序

現在,如果我們想按Employee對象的id字段對地圖值進行排序怎麼辦?我們也可以使用ArrayList

首先,讓我們將值複製到列表中:

List<Employee> employeeById = new ArrayList<>(map.values());

然後,我們對其進行排序:

Collections.sort(employeeById);

請記住,這Comparable**因為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字段排序。

4.使用TreeSet

如果我們不想在已排序的集合中接受重複的值,則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<String> keySet = new TreeSet<>(map.keySet());

讓我們打印keySet並查看輸出:

[Annie, George, John, Mher]

現在,我們對地圖鍵進行了排序,沒有重複項。

4.2。按值排序

同樣,對於映射值,轉換代碼如下所示:

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'}]

如我們所見,輸出中沒有重複項。當我們覆蓋equalshashCode.時,此方法適用於自定義對象hashCode.

5.使用Lambda和流

從Java 8開始,我們可以使用Stream API和lambda表達式對map進行排序。我們所需要的只是在地圖的stream管道上調用sorted方法。

5.1。按鍵排序

要按鍵排序,我們使用comparingByKey比較器:

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'}

默認情況下,排序模式為升序。

5.2。按值排序

當然,我們也可以按Employee對象排序:

map.entrySet()

 .stream()

 .sorted(Map.Entry.comparingByValue())

 .forEach(System.out::println);

如我們所見,上面的代碼打印出一張按Employee對象的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'}

此外,我們可以將結果收集到新地圖中:

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));

請注意,我們將結果收集到LinkedHashMap默認情況下, Collectors.toMap返回一個新的HashMap,但眾所周知, HashMap不保證迭代**順序**,LinkedHashMap可以保證

6.使用番石榴

最後,允許我們對HashMap進行排序的庫是Guava。在開始之前,檢查有關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上找到討論期間使用的代碼。