Apache Commons BeanUtils 庫提供的 BeanComparator 類雖然能對 JavaBean 進行排序,但每次只能針對單一屬性。在實際開發中,經常需要先按「姓名」排序,姓名相同再按「年齡」排序這類多級排序需求。本文提供一個通用的 ListSorter 工具類,優雅地解決這一問題。
利用 Java 的 Comparator 鏈式比較機制,依次遍歷指定的屬性數組,優先比較第一個屬性,僅當比較結果為 0(相等)時才繼續比較下一個屬性。
import org.apache.commons.beanutils.BeanComparator;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* List 元素多屬性排序工具類
*/
@SuppressWarnings({"unchecked"})
public class ListSorter {
/**
* 對 List 元素的多個屬性進行排序
* 例如 ListSorter.sort(list, "name", "age"),則先按 name 排序,name 相同的元素按 age 排序
*
* @param list 包含要排序元素的 List
* @param properties 要排序的屬性,前面的值優先級高
*/
public static <V> void sort(List<V> list, final String... properties) {
Collections.sort(list, new Comparator<V>() {
public int compare(V o1, V o2) {
// 處理 null 值情況
if (o1 == null && o2 == null) return 0;
if (o1 == null) return -1;
if (o2 == null) return 1;
// 依次比較各屬性
for (String property : properties) {
Comparator c = new BeanComparator(property);
int result = c.compare(o1, o2);
if (result != 0) {
return result; // 只要有屬性分出勝負,直接返回
}
}
return 0; // 所有屬性都相等
}
});
}
}
// 假設 User 類有 name、age、salary 屬性 List<User> users = getUserList(); // 先按部門排序,部門相同按薪資降序,薪資相同按年齡升序 ListSorter.sort(users, "department", "salary", "age");
<V> 泛型確保類型安全String... properties 允許動態指定任意數量的排序屬性null 元素視為最小值,避免 NullPointerExceptionComparable 接口(如 String、Integer、Date 等)userName 對應 getUserName())BeanComparator 或使用 Collections.reverseOrder() 組合這個工具類代碼簡潔、復用性強,可直接集成到項目中解決多數多字段排序場景,避免重複造輪子。