您的位置:首頁>正文

整理關於專案裡面中文資料排序問題解決方案

我們在應用程式中可能會經常遇到對中文排序的問題, 例如姓名列表, 詞彙表等等。 對中文排序, 我們使用比較多的是根據中文拼音發音來確定順序。

我們可能會經常使用

java.util.Set

介面,

java.util.Arrays.sort((T[] a, Comparator c))

等類或方法對含有中文字元的物件進行排序, 但是這些在預設情況下都是調用

String.CompareTo(String)

方法, 這個方法是比較2個字元的 codepoint value, 如果第一個字元的值小於第二個, 則在排序結果中第一個會在前面, 反之亦然。

java.text.Collator

介面及其實現類

其實 java 中提供了和語言相關的類, 即 Collator 介面及其實現類。

java.text.RuleBasedCollator

是一個具體類, 它實現了 Comparator 介面中的 compare(Object, Object) 方法。 RuleBasedCollator 根據根據特定語言的預設規則比較字元,

也可以按照指定的規則來比較, 請參閱 java API 獲取此類的詳細信 息。

如果我們需要對一個有中文的陣列進行排序, 則可以使用這個類。 請看如下示例代碼:

import java.util.*;

import java.text.*;

public class Test

{

String [] test = new String [] {

"作業" ,

"測試" ,

"test" ,

"我們" ,

"。 空" ,

"鏤空" ,

"[" ,

"瀏" ,

"皙"

};

java.util.Arrays .sort(test,

(RuleBasedCollator )Collator .getInstance(Locale .CHINA));

System .out.println("============" );

for (String key : test)

System .out.println(key);

}

以上代碼的輸出結果為:

============

[

test

。 空

測試

我們

作業

鏤空

大家可能會發現只有一部分漢字是按照中文拼音排序了, 還有幾個沒有。

問題分析:

GB2312:

在簡體中文中我們使用比較多的字元集是 GB2312-80, 簡稱為 GB2312, 這個字元集包含了目前最常用的漢字共計 6736 個。 其中的漢字分為兩大類:

常用漢字

次常用漢字

常用漢字按照中文拼音來排序, 而次常用漢字按照筆劃部首進行排序。

簡體漢字在 Unicode 中一般是按照 gb2312 的碼點值的順序來放置的, 所以如果是常用漢字 java 就能夠很準確的進行排序, 但如果是次常用漢字, 則就會出現問題。 在以上示例中, "鏤", "皙" 屬於次常用字。

解決方案:

RuleBasedCollator 類 getRules() 方法可以返回對應語言的規則設置。 簡體中文對應的規則是 gb2312 所對應的字元。

我們可以把其中的全部漢字提取出來

對這些漢字重新排序

利用RuleBasedCollator(String rules) 構造器新建一個定制的 RuleBasedCollator

參考代碼

在以下的代碼中, 我把排過序的漢字直接作為 String 物件放在類裡面了, 如果要讓代碼變得簡潔一些, 則可以把完整的規則(特殊字元+排序漢字)存為檔。

package sorting;

import java.util.*;

import java.text.*;

/**

* @author GaoJianMin

*

*/

public class ChineseGB2312Collator

{

/**

* @return a customized RuleBasedCollator with Chinese characters (GB2312) sorted correctly

*

*/

public static final RuleBasedCollator getFixedGB2312Collator()

{

RuleBasedCollator fixedGB2312Collator =null ;

try

{

fixedGB2312Collator = new java.text.RuleBasedCollator (

ChineseGB2312Collator.getGB2312SpecialChars() +

GB2312Chars

);

}catch (ParseException e)

{

e.printStackTrace();

}

return fixedGB2312Collator;

}

/**

* @return the special characters in GB2312 charset.

*

*/

public static final String getGB2312SpecialChars()

{

RuleBasedCollator zh_CNCollator = (RuleBasedCollator )Collator .getInstance(Locale .CHINA);

//index 2125 is the last symbol "╋"

return zh_CNCollator.getRules().substring(0,2125);

}

/**

* 6763 Chinese characters in GB2312 charset

*/

public static final String GB2312Chars =

"<吖<阿<啊< 錒<嗄<哎<哀<唉<埃<挨<鎄<捱<皚<癌<噯<矮<藹< 靄<艾<愛<砹<隘<嗌<嬡<礙<曖<璦<安<桉<氨<庵< 諳<鵪<鞍<俺<垵<銨<揞<犴<岸<按<案<胺<暗<黯< 肮<昂<盎<凹<坳<敖<嗷<廒<獒<遨<熬<翱<聱<螯< 鼇<鏖<拗<襖<媼<嶴<傲<奧<驁<澳<懊<鏊" +

"<八<巴<叭< 扒<吧<岜<芭<疤<捌<笆<粑<拔<茇<菝<跋<魃<把< 鈀<靶<壩<爸<罷<鮁<霸<灞<掰<白<百<佰<柏<捭< 擺<唄<敗<拜<稗<扳<班<般<頒<斑<搬<瘢<癍<阪< 阪<板<版<鈑<舨<辦<半<伴<扮<拌<絆<瓣<邦<幫< 梆<浜<綁<榜<膀<蚌<傍<棒<謗<蒡<磅<鎊<勹<包< 孢<苞<胞<煲<齙<褒<雹<寶<飽<保<鴇<堡<葆<褓< 報<抱<豹<趵<鮑<暴<爆<陂<卑<杯<悲<碑<鵯<北< 貝<狽<邶<備<背<鋇<倍<悖<被<憊<焙<輩<碚<蓓< 褙<韝<鐾<奔<賁<錛<本<苯<畚<坌<笨<崩<繃<嘣< 甭<泵<迸<甏<蹦<逼<荸<鼻<匕<比<吡<妣<彼<秕< 俾<筆<舭<鄙<幣<必<畢<閉<庇<畀<嗶<毖<蓽<陛< 斃<狴<鉍<婢<庳<敝<萆<弼<愎<篳<潷<痹<蓖<裨< 蹕<辟<弊<碧<箅<蔽<壁<嬖<篦<薜<避<濞<臂<髀< 璧<襞<邊<砭<籩<編<煸<蝙<鯿<鞭<貶<扁<窆<匾< 碥<褊<卞<弁<忭<汴<苄<拚<便<變<緶<遍<辨<辯< 辮<灬<杓<彪<標<颮<髟<驃<膘<瘭<鏢<飆<飆<鑣< 表<婊<裱<鰾<憋<鱉<別<蹩<癟<賓<彬<儐<斌<濱< 繽<檳<鑌<瀕<豳<擯<殯<臏<髕<鬢<冫<冰<兵<丙< 邴<秉<柄<炳<餅<稟<並<病<摒<撥<波<玻<剝<缽< 餑<啵<脖<菠<播<伯<孛<駁<帛<泊<勃<亳<鈸<鉑< 舶<博<渤<鵓<搏<箔<膊<踣<薄<礴<跛<簸<擘<檗< 逋<鈽<晡<醭<蔔<卟<補<哺<捕<不<布<步<怖<鈈< 部<埠<瓿<簿" ;

}

package sorting;

import java.util.*;

import java.text.*;

/**

* @author GaoJianMin

*

*/

public class ChineseGB2312Comparator implements Comparator , Comparable {

private RuleBasedCollator GB2312Collator =

ChineseGB2312Collator.getFixedGB2312Collator();

private String str1;

/**

* @param str1

*/

public ChineseGB2312Comparator(String str1) {

this .str1 = str1;

}

/**

*

*/

public ChineseGB2312Comparator() {

this .str1="" ;

}

/**

* @param str1

* @param str2

* @return an integer indicatint the comparison result

* @see java.util.Comparator#compare(Object, Object)

*/

public int compare(String str1, String str2) {

return GB2312Collator.compare(str1, str2);

}

/**

* @param str2

* @return an integer indicatint the comparison result

* @see java.lang.Comparable#compareTo(Object)

*/

public int compareTo(String str2) {

return GB2312Collator.compare(str1, str2);

}

}

測試代碼及結果

代碼:

import java.util.*;

import java.text.*;

public class Test

{

String [] test = new String [] {

"作業" ,

"測試" ,

"test" ,

"我們" ,

"。空" ,

"鏤空" ,

"[" ,

"瀏" ,

"皙"

};

java.util.Arrays .sort(test, new ChineseGB2312Comparator());

System .out.println("============" );

for (String key : test)

System .out.println(key);

}

請大家多度關注我的頭條號,謝謝大家!

測試代碼及結果

代碼:

import java.util.*;

import java.text.*;

public class Test

{

String [] test = new String [] {

"作業" ,

"測試" ,

"test" ,

"我們" ,

"。空" ,

"鏤空" ,

"[" ,

"瀏" ,

"皙"

};

java.util.Arrays .sort(test, new ChineseGB2312Comparator());

System .out.println("============" );

for (String key : test)

System .out.println(key);

}

請大家多度關注我的頭條號,謝謝大家!

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示