Collator 是**區域敏感字串比較器**,支援按語言規則排序。對中文,`Locale.CHINA`(大陸簡體)、`Locale.TAIWAN`(繁體)、`Locale.CHINESE`(通用)對應不同排序規則。
Listbooks = Arrays.asList("英語", "日語", "德語", "法語", "俄語"); Collator collator = Collator.getInstance(Locale.CHINA); books.sort(collator::compare); // 結果:德語、俄語、法語、英語、日語(按拼音首字母 d, e, f, y, r)
public class Book {
private String id, name, publisher;
// 構造器、getter、toString
}
public class ChineseBookComparator implements Comparator {
private final Collator collator = Collator.getInstance(Locale.CHINA);
@Override
public int compare(Book b1, Book b2) {
return collator.compare(b1.getName(), b2.getName());
}
}
// 使用
List list = new ArrayList<>();
list.add(new Book("1", "英語", "外語出版社"));
list.add(new Book("2", "日語", "東方出版社"));
list.add(new Book("3", "德語", "外語出版社"));
Collections.sort(list, new ChineseBookComparator());
// 或 list.sort(new ChineseBookComparator());
| 強度級別 | 常量 | 比較行為 | 中文效果 |
|---|---|---|---|
| PRIMARY | Collator.PRIMARY | 僅比較基礎字母/拼音 | 忽略聲調:ma = má = mǎ = mà |
| SECONDARY | Collator.SECONDARY | 基礎 + 聲調/重音 | ma < má < mǎ < mà |
| TERTIARY | Collator.TERTIARY | 基礎 + 聲調 + 大小寫/寬窄 | 全角/半角、大小寫區分 |
| IDENTICAL | Collator.IDENTICAL | 所有差異(含控制字符) | 最嚴格,極少用 |
<dependency>
<groupId>com.ibm.icu</groupId>
<artifactId>icu4j</artifactId>
<version>74.2</version>
</dependency>
import com.ibm.icu.text.Collator; import com.ibm.icu.util.ULocale; Collator strokeCollator = Collator.getInstance(ULocale.CHINA); strokeCollator.setAttribute(UCollAttribute.COLLATION_STRENGTH, UCollAttributeValue.SECONDARY); // 設置為筆畫排序(需 CLDR 數據支援,具體屬性視 ICU 版本) // ICU 也支援部首排序、拼音+筆畫混合排序
@Component
public class BookSortService {
private static final Collator PINYIN_COLLATOR = Collator.getInstance(Locale.CHINA);
private static final Collator STROKE_COLLATOR = initStrokeCollator(); // ICU4J
public List sortByPinyin(List books) {
return books.stream()
.sorted(Comparator.comparing(Book::getName, PINYIN_COLLATOR))
.collect(Collectors.toList());
}
public List sortByStroke(List books) {
return books.stream()
.sorted(Comparator.comparing(Book::getName, STROKE_COLLATOR))
.collect(Collectors.toList());
}
// 支援多字段:書名拼音升序 + 出版社筆畫降序
public List sortMulti(List books) {
return books.stream()
.sorted(Comparator
.comparing(Book::getName, PINYIN_COLLATOR)
.thenComparing(Book::getPublisher, Comparator.comparing(s -> s, STROKE_COLLATOR).reversed()))
.collect(Collectors.toList());
}
}
| 問題 | 原因 | 解決 |
|---|---|---|
| 排序結果不符預期 | Locale 錯誤(用了 US/默認) | 強制 `Locale.CHINA` 或 `Locale.TAIWAN` |
| 大數據量排序慢 | 重複創建 Collator / 比較器 | 單例複用、預提取排序鍵 |
| 數字/英文夾雜排序亂序 | Collator 預設 Unicode 碼點序 | 預處理:數字補零、英文統一大小寫、或分組排序 |
| 簽名衝突 | Comparator.comparing 參數類型推導失敗 | 顯式指定 `Comparator.comparing(Book::getName, (Collator) collator)` |
Java 原生 `Collator` 解決**拼音/聲調**排序;**筆畫/部首**需 ICU4J。核心模式:**單例 Collator + Comparator.comparing + Stream 排序**,簡潔高效,適配國際化業務。