按日期對列表中的對象進行排序
一、概述
在本教程中,我們將討論按日期對List
中的對象進行排序。大多數排序技術或示例都允許用戶按字母順序對列表進行排序,但在本文中,我們將討論如何使用Date
對象進行排序。
我們將研究使用 Java 的Comparator
類對列表的值進行自定義排序。
2. 設置
讓我們看看我們將在本文中使用的Employee
實體:
public class Employee implements Comparable<Employee> {
private String name;
private Date joiningDate;
public Employee(String name, Date joiningDate) {
// ...
}
// standard getters and setters
}
我們可以注意到我們在Employee
類中實現了一個Comparable
接口。這個接口讓我們定義一個策略來比較對象和其他相同類型的對象。這用於以自然排序形式或由compareTo()
方法定義的對像對對象進行排序。
3. 使用Comparable
排序
在 Java 中,自然順序是指我們應該如何對數組或集合中的基元或對象進行排序。 java.util.Arrays
和java.util.Collections
的sort()
方法應該是一致的,並反映相等的語義。
我們將使用此方法來比較當前對象和作為參數傳遞的對象:
public class Employee implements Comparable<Employee> {
// ...
@Override
public boolean equals(Object obj) {
return ((Employee) obj).getName().equals(getName());
}
@Override
public int compareTo(Employee employee) {
return getJoiningDate().compareTo(employee.getJoiningDate());
}
}
此compareTo()
方法會將當前對象與作為參數發送的對象進行比較。在上面的示例中,我們將當前對象的加入日期與傳遞的 Employee 對象進行比較。
3.1。按升序排序
在大多數情況下, compareTo()
方法描述了使用自然排序在對象之間進行比較的邏輯。在這裡,我們將員工的入職日期字段與其他同類對象進行比較。如果兩個員工的加入日期相同,則他們將返回 0:
@Test
public void givenEmpList_SortEmpList_thenSortedListinNaturalOrder() {
Collections.sort(employees);
assertEquals(employees, employeesSortedByDateAsc);
}
現在, Collections.sort(employees)
將根據其joiningDate
而不是其主鍵或名稱對員工列表進行排序。我們可以看到列表是按照Employee
joiningDate
的自然順序:
[(Pearl,Tue Apr 27 23:30:47 IST 2021),
(Earl,Sun Feb 27 23:30:47 IST 2022),
(Steve,Sun Apr 17 23:30:47 IST 2022),
(John,Wed Apr 27 23:30:47 IST 2022)]
3.2.按降序排序
Collections.reverseOrder()
方法對對象進行排序,但按照自然排序的相反順序。這將返回一個比較器,它將反向執行排序。當對像在比較中返回null
時,它會拋出NullPointerException
:
@Test
public void givenEmpList_SortEmpList_thenSortedListinDescOrder() {
Collections.sort(employees, Collections.reverseOrder());
assertEquals(employees, employeesSortedByDateDesc);
}
4. 使用Comparator
器排序
4.1。按升序排序
現在讓我們使用Comparator
接口實現對我們的員工列表進行排序。在這裡,我們將動態傳遞一個匿名內部類參數給Collections.sort()
API:
@Test
public void givenEmpList_SortEmpList_thenCheckSortedList() {
Collections.sort(employees, new Comparator<Employee>() {
public int compare(Employee o1, Employee o2) {
return o1.getJoiningDate().compareTo(o2.getJoiningDate());
}
});
assertEquals(employees, employeesSortedByDateAsc);
}
我們還可以用 Java 8 Lambda 語法替換此語法,這會使我們的代碼更小,如下所示:
@Test
public void givenEmpList_SortEmpList_thenCheckSortedListAscLambda() {
Collections.sort(employees, Comparator.comparing(Employee::getJoiningDate));
assertEquals(employees, employeesSortedByDateAsc);
}
compare(arg1, arg2)
方法接受兩個泛型類型的參數並返回一個整數。由於它與類定義分離,我們可以根據不同的變量和實體定義自定義比較。當我們想要定義不同的自定義排序來比較參數對象時,這很有用。
4.2.按降序排序
我們可以通過反轉員工對像比較,即比較Employee2
和Employee1
來對給定的Employee
列表進行降序排序。這將反轉比較,從而以降序返回結果:
@Test
public void givenEmpList_SortEmpList_thenCheckSortedListDescV1() {
Collections.sort(employees, new Comparator<Employee>() {
public int compare(Employee emp1, Employee emp2) {
return emp2.getJoiningDate().compareTo(emp1.getJoiningDate());
}
});
assertEquals(employees, employeesSortedByDateDesc);
}
我們還可以使用 Java 8 Lambda 表達式將上述方法轉換為更簡潔的形式。這將執行與上述函數相同的功能,唯一的區別是與上述代碼相比,該代碼包含的代碼行更少。儘管這也使代碼的可讀性降低。在使用 Comparator 時,我們為Collections.sort()
API 動態傳遞了一個匿名內部類:
@Test
public void givenEmpList_SortEmpList_thenCheckSortedListDescLambda() {
Collections.sort(employees, (emp1, emp2) -> emp2.getJoiningDate().compareTo(emp1.getJoiningDate()));
assertEquals(employees, employeesSortedByDateDesc);
}
5. 結論
在本文中,我們探討瞭如何以升序和降序模式按Date
對像對 Java Collection 進行排序。
我們還簡要介紹了 Java 8 的 lambda 特性,這些特性有助於排序並有助於使代碼簡潔。
與往常一樣,本文中使用的完整代碼示例可以在 GitHub 上找到。