遇到了一個對包含中文的字符串進行排序的問題。要求按unicode編碼對字符串進行排序。
測試字符串數組如下:
1
2
3
4
5
6
7
8
|
string[] arr = { "1-測試" , "1-編輯" , "1-營銷" , "1結束" , "2-測試" , "1-qt" }; |
按unicode排序的期望結果應該是這樣的:
1-編輯, 1-測試, 1-營銷, 1-qt, 1結束, 2-測試
先按java.lang.string類提供的默認比較方案進行實現,大致如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import java.util.arrays; import java.util.comparator; public class myjob { public static void main(string[] args) { string[] arr = { "1-測試" , "1-編輯" , "1-營銷" , "1結束" , "2-測試" , "1-qt" }; comparator<string> c = string::compareto; arrays.sort(arr, c); system.out.println(arrays.tostring(arr)); } } |
結果如下:
[1-qt, 1-測試, 1-編輯, 1-營銷, 1結束, 2-測試]
可以看到中文字符不能按照拼音進行排序。這時最直接的思路就是將中文字符轉為拼音后再進行排序。但是要注意下,在這里面有個字符串不包含中文字符,這就容易導致順序混亂。
如下面這幾個字符串按拼音進行排序順序如下:
1-編輯,1-測試,1-qt,1-營銷
可以看到字符串“1-qt”的位置出錯了。 但是按拼音來說它的位置又是對的。這不能不說是一個讓人有些頭疼的地方。
不過不用擔心,java提供了java.text.collator類來支持規范化的字符串比較。
使用collator來改造之前的代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import java.text.collator; import java.util.arrays; import java.util.comparator; import java.util.locale; public class myjob { public static void main(string[] args) { string[] arr = { "1-測試" , "1-編輯" , "1-營銷" , "1結束" , "2-測試" , "1-qt" }; comparator<string> c = (o1, o2) -> collator.getinstance(locale.chinese).compare(o1, o2); arrays.sort(arr, c); system.out.println(arrays.tostring(arr)); } } |
改造后的程序執行排序的結果如下:
[1-qt, 1-編輯, 1-測試, 1結束, 1-營銷, 2-測試]
結果看著好像還ok。但是停停、注意下、字符串“1結束”的位置好像比較奇妙,理想情況下它應該在“1-營銷”的后面。
這里出問題的原因我沒有弄清楚。猜測著應該是java在chinese語法中將中劃線處理為空字符了。不過最根本的問題還是java對unicode collation algorithm(uca,unicode整理算法)的支持并不好。
此時可以考慮使用ibm icu提供的collator來替換jdk默認的collator。代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import com.ibm.icu.text.collator; import java.util.arrays; import java.util.comparator; import java.util.locale; public class myjob { public static void main(string[] args) { string[] arr = { "1-測試" , "1-編輯" , "1-營銷" , "1結束" , "2-測試" , "1-qt" }; comparator<string> c = (o1, o2) -> collator.getinstance(locale.chinese).compare(o1, o2); arrays.sort(arr, c); system.out.println(arrays.tostring(arr)); } } |
相關的依賴為:
1
2
3
4
5
|
<dependency> <groupid>com.ibm.icu</groupid> <artifactid>icu4j-localespi</artifactid> <version> 60.2 </version> </dependency> |
執行結果為:
[1-編輯, 1-測試, 1-營銷, 1-qt, 1結束, 2-測試]
可以看到是和預期一致的。
總結
原文鏈接:http://www.zhyea.com/2018/10/30/java-string-in-chinese-sort-with-unicode.html