Java自定義比較器實現中文排序
阿新 • • 發佈:2019-02-19
compareTo 方法
compareTo()是兩個字串物件比較大小,返回一個整數值,如果呼叫字串物件大,返回正整數,反之,返回負整數。相等則返回0。compareTo()是兩個字串物件按ASCII比較大小(漢字是Unicode),返回一個整數值,如果呼叫字串物件大,返回正整數,反之,返回負整數。相等則返回0。
Comparator 比較器
Java 內實現自定義比較器比較簡單,實現Comparator介面的compare()這個方法來制定排序規則,按照Java規範應滿足以下約定,否則會拋Comparison method violates its general contract 異常。規則如下:
同時應滿足以下約定:
+ 自反性 sgn(compare(x, y)) == -sgn(compare(y, x))
+ 傳遞性 compare(x, y) > 0 compare(y, z)>0) =>得出 compare(x, z)>0
+ 一致性 (compare(x, y)==0) == (x.equals(y)),這點規範中原文是“not strictly required”,不是必須的,但是實現者應該知道不一致的後果,所以儘量實現這一要求.
Comparator<String> comparator = new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.compareTo(s2);
}
};
以下程式碼示例:
@Test
public void testCompare() {
List<String> list = new ArrayList<>();
list.add("java");
list.add("php");
list.add("c++");
System.out.println("排序前-->" + list);
Comparator<String> comparator = new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.compareTo(s2);
}
};
Collections.sort(list, comparator);
System.out.println("排序後-->" + list);
Collections.reverse(list);
System.out.println("排序後逆序-->" + list);
}
輸出結果為:
Comparator中文排序
中文漢字是Unicode編碼,所以排序時不是我們習慣用的拼音字母。如果還是剛才的實現,程式碼如下:
@Test
public void testCompareCN() {
List<String> list = new ArrayList<>();
list.add("中國");// 中->20013 unicode編碼的4E2D
list.add("英國");// 英-->33521 unicode編碼的82F1
list.add("美國");// 美->32654 unicode編碼的7F8E
// 漢字unicode編碼表 http://www.chi2ko.com/tool/CJK.htm
System.out.println("排序前-->" + list);
Comparator<String> comparator = new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
int b = s1.compareTo(s2);
return b;
}
};
Collections.sort(list, comparator);
System.out.println("排序後-->" + list);
Collections.reverse(list);
System.out.println("排序後逆序-->" + list);
// 輸出字元編碼對應的十進位制
//char a = '美';
//System.out.println((int) a);
}
輸出結果為:
這個結果不符合我們的排序習慣,因此應該用Collator指定Locale.CHINA,程式碼應如下:
@Test
public void testCollator() {
List<String> list = new ArrayList<>();
list.add("中國");
list.add("英國");
list.add("美國");
System.out.println("排序前-->" + list);
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
String o1 = "";
String o2 = "";
if (s1 != null) {
o1 = s1;
}
if (s2 != null) {
o2 = s2;
}
Collator instance = Collator.getInstance(Locale.CHINA);
return instance.compare(o1, o2);
}
});
System.out.println("排序後-->" + list);
Collections.reverse(list);
System.out.println("排序後逆序-->" + list);
}
輸出結果為:
需要注意的是,compareTo不能傳入null,自定義比較器時要注意。