📘 Java 中文排序教學文檔(基于 Collator)
🧠 目錄
- 概述
- Java 中字符串排序的默認行為
- 為什么需要 Collator
- 使用 Collator 進行中文排序
- 升序 vs 降序排序
- 自定義對象字段排序
- 多字段排序示例
- 總結對比表
- 附錄:完整代碼示例
1. 📌 概述
Java 的 List.sort()
方法通過傳入一個比較器(Comparator
),決定集合中元素的排列順序。但 Java 默認的字符串比較并不能正確排序中文(尤其是按拼音順序),這就需要使用 Collator
來實現符合中文語義的排序方式。
2. 🔍 Java 中字符串排序的默認行為
Java 默認使用 Unicode 編碼值 進行字符串比較:
List<String> list = Arrays.asList("張三", "李四", "王五");
Collections.sort(list); // 默認排序方式
此時的排序結果可能是亂碼或者無意義的順序,因為它只是按字符的 Unicode 值排列。
3. ? 為什么需要 Collator
java.text.Collator
是 Java 提供的 本地化字符串比較工具類,支持中文、日文、韓文等語言規則的比較。
使用 Collator 可以實現:
- 按拼音排序(中文首字母)
- 支持不同 Locale(本地語言規則)
4. ? 使用 Collator 進行中文排序
基本示例:
import java.text.Collator;
import java.util.*;public class ChineseSortExample {public static void main(String[] args) {List<String> names = Arrays.asList("張三", "李四", "王五");Collator collator = Collator.getInstance(Locale.CHINA);names.sort(collator); // 升序:拼音 A → ZSystem.out.println(names);}
}
5. 🔼 升序 vs 🔽 降序排序
升序(拼音從 A → Z):
list.sort((a, b) -> Collator.getInstance(Locale.CHINA).compare(a, b));
降序(拼音從 Z → A):
list.sort((a, b) -> Collator.getInstance(Locale.CHINA).compare(b, a));
? 記憶技巧:
compare(a, b)
表示“a 和 b 誰更小”,如果返回負數表示 a 更小,應該排前面;若返回正數表示 a 更大,應該排后面。
6. 🧾 自定義對象字段排序(按對象中的中文字段)
如果你有如下對象:
class Person {private String name;public String getName() { return name; }
}
你可以按 name
字段排序:
升序:
list.sort((o1, o2) ->Collator.getInstance(Locale.CHINA).compare(o1.getName(), o2.getName()));
降序:
list.sort((o1, o2) ->Collator.getInstance(Locale.CHINA).compare(o2.getName(), o1.getName()));
7. 🌈 多字段排序示例
如果你想先按姓名拼音降序,再按時間升序,可以這樣寫:
list.sort((o1, o2) -> {Collator collator = Collator.getInstance(Locale.CHINA);int nameCompare = collator.compare(o2.getName(), o1.getName()); // 姓名降序if (nameCompare != 0) return nameCompare;return o1.getCreateTime().compareTo(o2.getCreateTime()); // 時間升序
});
8. 📊 總結對比表
方式 | 寫法 | 效果 |
---|---|---|
默認排序 | Collections.sort(list) | 按 Unicode 排序,中文不正確 |
拼音升序 | compare(a, b) | 拼音 A → Z |
拼音降序 | compare(b, a) | 拼音 Z → A |
對象字段升序 | compare(o1.getField(), o2.getField()) | 自定義字段排序 |
對象字段降序 | compare(o2.getField(), o1.getField()) | 字段降序 |
多字段組合 | 使用 if (result != 0) 判斷后繼續比較第二字段 | 多條件排序 |
9. 🧪 附錄:完整中文排序對象示例
import java.text.Collator;
import java.util.*;class User {private String commitUser;private Date commitTime;public User(String commitUser, Date commitTime) {this.commitUser = commitUser;this.commitTime = commitTime;}public String getCommitUser() { return commitUser; }public Date getCommitTime() { return commitTime; }@Overridepublic String toString() {return commitUser + " - " + commitTime;}
}public class ChineseSort {public static void main(String[] args) {List<User> users = new ArrayList<>();users.add(new User("李四", new Date(100000)));users.add(new User("王五", new Date(50000)));users.add(new User("陳七", new Date(150000)));users.sort((o1, o2) -> {Collator collator = Collator.getInstance(Locale.CHINA);int nameCmp = collator.compare(o2.getCommitUser(), o1.getCommitUser()); // 名字降序if (nameCmp != 0) return nameCmp;return o1.getCommitTime().compareTo(o2.getCommitTime()); // 時間升序});users.forEach(System.out::println);}
}