用Java對HashMap排序
1.簡介
在本快速教程中,我們將學習如何在Java中對HashMap
**進行排序**。
更具體地說,我們將研究使用以下項按鍵或值對HashMap
條目進行排序:
-
TreeMap
-
ArrayList
和Collections.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'}]
如我們所見,輸出中沒有重複項。當我們覆蓋equals
和hashCode.
時,此方法適用於自定義對象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上找到討論期間使用的代碼。