預設字串比較依據 Unicode 碼位,中文字符按編碼順序排列,不符合拼音、筆畫或部首等語言習慣排序規則。TreeMap 預設使用自然排序(Comparable),直接存入中文鍵值會產生非預期順序。
import java.text.Collator;
import java.text.CollationKey;
import java.util.Comparator;
public class CollatorComparator implements Comparator<Object> {
private final Collator collator = Collator.getInstance(); // 依據 Locale 取得
@Override
public int compare(Object o1, Object o2) {
String s1 = o1.toString();
String s2 = o2.toString();
CollationKey key1 = collator.getCollationKey(s1);
CollationKey key2 = collator.getCollationKey(s2);
return key1.compareTo(key2);
}
}
getInstance() 預設使用系統 Locale,可指定 Collator.getInstance(Locale.TRADITIONAL_CHINESE)collator.compare(),適合大量排序collator.setStrength(Collator.PRIMARY/SECONDARY/TERTIARY/IDENTICAL) 控制比較敏感度(基礎字符/重音/大小寫/完全相同)
TreeMap<String, String> map = new TreeMap<>(new CollatorComparator());
map.put("1", "1");
map.put("華", "華");
map.put("花", "花");
for (String v : map.values()) {
System.out.println(v);
}
1 花 華
符合注音/拼音排序規則(ㄏㄨㄚ 先於 ㄏㄨㄚˊ)。
// 針對台灣繁體中文環境
Collator twCollator = Collator.getInstance(Locale.TRADITIONAL_CHINESE);
twCollator.setStrength(Collator.TERTIARY); // 區分大小寫、重音
// 針對大陸簡體中文環境
Collator cnCollator = Collator.getInstance(Locale.SIMPLIFIED_CHINESE);
cnCollator.setDecomposition(Collator.FULL_DECOMPOSITION); // 處理兼容字符
Collator.getInstance(Locale) 快取機制:同一 Locale 多次呼叫返回同一實例| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| Collator + TreeMap | 標準 API、支援多語系、可調強度 | 效能較原生比較低 | 一般業務排序、多語系應用 |
| ICU4J Collator | 功能更強、支援 CLDR、排序規則更豐富 | 需額外依賴、體積較大 | 專業語言處理、複雜排序規則 |
| 拼音轉換後排序 | 邏輯直觀、效能佳 | 需第三方庫、多音字處理複雜 | 純中文環境、對拼音排序有嚴格要求 |