Java中List按自定義順序排序的幾種實現(xiàn)過程
在實際開發(fā)中,我們經(jīng)常需要對集合中的對象按照特定字段進行排序。當排序規(guī)則不是簡單的字母或數(shù)字順序,而是自定義的順序時,我們需要采用特殊的方法。
本文將以一個List<Person>按省份特定順序(北京、上海、廣州、深圳)排序為例,介紹幾種實現(xiàn)方案并分析它們的優(yōu)缺點。
問題描述
我們有一個Person類:
@Data
public class Person {
private String name;
private int age;
private String province;
}
需要將List<Person>按照省份的特定順序排序:北京 > 上海 > 廣州 > 深圳,其他省份排在最后。
解決方案
方案1:使用Map定義順序權(quán)重
Map<String, Integer> provinceOrder = Map.of(
"北京", 1,
"上海", 2,
"廣州", 3,
"深圳", 4
);
persons.sort(Comparator.comparingInt(
p -> provinceOrder.getOrDefault(p.getProvince(), Integer.MAX_VALUE)
));
優(yōu)點:
- 實現(xiàn)簡單直觀
- 易于修改順序(只需調(diào)整Map)
- 性能良好(O(1)的查找復雜度)
缺點:
- 需要額外維護一個Map
- 順序修改時需要重建Map
方案2:使用Enum定義順序
enum ProvincePriority {
BEIJING("北京", 1),
SHANGHAI("上海", 2),
GUANGZHOU("廣州", 3),
SHENZHEN("深圳", 4),
OTHER("其他", Integer.MAX_VALUE);
private final String name;
private final int priority;
// 構(gòu)造函數(shù)、getter等
public static int getPriority(String provinceName) {
return Arrays.stream(values())
.filter(pp -> pp.name.equals(provinceName))
.findFirst()
.orElse(OTHER)
.getPriority();
}
}
persons.sort(Comparator.comparingInt(
p -> ProvincePriority.getPriority(p.getProvince())
));
優(yōu)點:
- 類型安全
- 可擴展性強
- 易于維護(相關(guān)邏輯封裝在Enum中)
缺點:
- 實現(xiàn)稍復雜
- 需要定義額外的Enum類
方案3:使用List.indexOf方法
List<String> order = List.of("北京", "上海", "廣州", "深圳");
persons.sort(Comparator.comparingInt(p -> {
int index = order.indexOf(p.getProvince());
return index == -1 ? Integer.MAX_VALUE : index;
}));
優(yōu)點:
- 代碼簡潔
- 順序直觀可見(直接寫在List中)
缺點:
- 每次比較都需要查找索引(O(n)復雜度)
- 性能不如前兩種方案
性能比較
對于大數(shù)據(jù)量排序的性能表現(xiàn):
- Map方案:最佳,因為Map的查找是O(1)復雜度
- Enum方案:與Map方案相當,但可能稍慢(取決于Enum實現(xiàn))
- List.indexOf方案:最差,因為每次比較都需要遍歷List
最佳實踐建議
- 小數(shù)據(jù)量:三種方案都可以,選擇最易讀的(通常是方案3)
- 大數(shù)據(jù)量:優(yōu)先選擇方案1或方案2
- 需要強類型檢查:選擇方案2
- 順序可能頻繁變更:選擇方案1
擴展思考
多級排序:可以在Comparator中添加thenComparing實現(xiàn)多級排序
persons.sort(Comparator
.comparingInt(p -> provinceOrder.getOrDefault(p.getProvince(), Integer.MAX_VALUE))
.thenComparing(Person::getAge)
);
動態(tài)順序:可以從數(shù)據(jù)庫或配置文件中加載排序規(guī)則,實現(xiàn)動態(tài)排序
空值處理:需要考慮province為null的情況,可以在Comparator中添加null處理
總結(jié)
在Java中實現(xiàn)自定義順序排序有多種方式,選擇哪種方案取決于具體場景:
- 簡單場景:使用List.indexOf方案(方案3)
- 一般場景:推薦使用Map方案(方案1)
- 復雜/企業(yè)級應用:考慮使用Enum方案(方案2)
無論選擇哪種方案,保持代碼的可讀性和可維護性都是最重要的考量因素。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Hikari連接池使用SpringBoot配置JMX監(jiān)控實現(xiàn)
Hikari是Spring Boot默認的數(shù)據(jù)庫連接池。區(qū)別于C3P0直接通過連接池對象獲取各項狀態(tài)指標,Hikari需要通過JMX來獲取。本文就詳細的來介紹一下,感興趣的可以了解一下2021-07-07
如何將char類型的數(shù)字字符轉(zhuǎn)換成int類型問題
這篇文章主要介紹了如何將char類型的數(shù)字字符轉(zhuǎn)換成int類型問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12
java中的Io(input與output)操作總結(jié)(三)
這一節(jié)我們來講Scanner類和PrintWriter類的用法,感興趣的朋友可以了解下2013-01-01
Java虛擬機使用jvisualvm工具遠程監(jiān)控tomcat內(nèi)存
這篇文章主要介紹了Java虛擬機使用jvisualvm工具遠程監(jiān)控tomcat內(nèi)存,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-11-11
java 畫pdf用itext調(diào)整表格寬度、自定義各個列寬的方法
這篇文章主要介紹了java 畫pdf用itext調(diào)整表格寬度、自定義各個列寬的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01
如何巧用HashMap一行代碼統(tǒng)計單詞出現(xiàn)次數(shù)詳解
這篇文章主要給大家介紹了關(guān)于如何巧用HashMap一行代碼統(tǒng)計單詞出現(xiàn)次數(shù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2020-07-07
Java開發(fā)之內(nèi)部類對象的創(chuàng)建及hook機制分析
這篇文章主要介紹了Java開發(fā)之內(nèi)部類對象的創(chuàng)建及hook機制,結(jié)合實例形式分析了java基于hook機制內(nèi)部類對象的創(chuàng)建與使用,需要的朋友可以參考下2018-01-01
springboot整合shiro實現(xiàn)登錄驗證授權(quán)的過程解析
這篇文章主要介紹了springboot整合shiro實現(xiàn)登錄驗證授權(quán),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-01-01

