Java 中文字符按Unicode排序的實(shí)現(xiàn)方法
遇到了一個(gè)對包含中文的字符串進(jìn)行排序的問題。要求按unicode編碼對字符串進(jìn)行排序。
測試字符串?dāng)?shù)組如下:
String[] arr = { "1-測試", "1-編輯", "1-營銷", "1結(jié)束", "2-測試", "1-qt" };
按unicode排序的期望結(jié)果應(yīng)該是這樣的:
1-編輯, 1-測試, 1-營銷, 1-qt, 1結(jié)束, 2-測試
先按java.lang.String類提供的默認(rèn)比較方案進(jìn)行實(shí)現(xiàn),大致如下:
import java.util.Arrays; import java.util.Comparator; public class MyJob { public static void main(String[] args) { String[] arr = { "1-測試", "1-編輯", "1-營銷", "1結(jié)束", "2-測試", "1-qt" }; Comparator<String> c = String::compareTo; Arrays.sort(arr, c); System.out.println(Arrays.toString(arr)); } }
結(jié)果如下:
[1-qt, 1-測試, 1-編輯, 1-營銷, 1結(jié)束, 2-測試]
可以看到中文字符不能按照拼音進(jìn)行排序。這時(shí)最直接的思路就是將中文字符轉(zhuǎn)為拼音后再進(jìn)行排序。但是要注意下,在這里面有個(gè)字符串不包含中文字符,這就容易導(dǎo)致順序混亂。
如下面這幾個(gè)字符串按拼音進(jìn)行排序順序如下:
1-編輯,1-測試,1-qt,1-營銷
可以看到字符串“1-qt”的位置出錯(cuò)了。 但是按拼音來說它的位置又是對的。這不能不說是一個(gè)讓人有些頭疼的地方。
不過不用擔(dān)心,java提供了java.text.Collator類來支持規(guī)范化的字符串比較。
使用Collator來改造之前的代碼:
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結(jié)束", "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)); } }
改造后的程序執(zhí)行排序的結(jié)果如下:
[1-qt, 1-編輯, 1-測試, 1結(jié)束, 1-營銷, 2-測試]
結(jié)果看著好像還OK。但是停停、注意下、字符串“1結(jié)束”的位置好像比較奇妙,理想情況下它應(yīng)該在“1-營銷”的后面。
這里出問題的原因我沒有弄清楚。猜測著應(yīng)該是java在Chinese語法中將中劃線處理為空字符了。不過最根本的問題還是java對Unicode Collation Algorithm(UCA,Unicode整理算法)的支持并不好。
此時(shí)可以考慮使用IBM ICU提供的Collator來替換jdk默認(rèn)的Collator。代碼如下:
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結(jié)束", "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)); } }
相關(guān)的依賴為:
<dependency> <groupId>com.ibm.icu</groupId> <artifactId>icu4j-localespi</artifactId> <version>60.2</version> </dependency>
執(zhí)行結(jié)果為:
[1-編輯, 1-測試, 1-營銷, 1-qt, 1結(jié)束, 2-測試]
可以看到是和預(yù)期一致的。
總結(jié)
相關(guān)文章
詳解java中this.getClass()和super.getClass()的實(shí)例
這篇文章主要介紹了詳解java中this.getClass()和super.getClass()的實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-08-08servlet之session簡介_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了servlet之session簡介,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07SpringBoot+WebSocket實(shí)現(xiàn)即時(shí)通訊功能(Spring方式)
今天給大家分享一個(gè)SpringBoot+WebSocket實(shí)現(xiàn)即時(shí)通訊功能(Spring方式),WebSocket是一種在單個(gè)TCP連接上進(jìn)行全雙工通信的協(xié)議,文章通過代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10修改Springboot默認(rèn)序列化工具Jackson配置的實(shí)例代碼
這篇文章主要介紹了如何修改Springboot默認(rèn)序列化工具Jackson的配置,當(dāng)Spring容器中存在多個(gè)同類型的Bean時(shí),默認(rèn)情況下最后一個(gè)創(chuàng)建的Bean將作為首選Bean,文中通過代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-02-02InputStreamReader和BufferedReader用法及實(shí)例講解
這篇文章主要介紹了InputStreamReader和BufferedReader用法及實(shí)例講解的相關(guān)資料,需要的朋友可以參考下2015-12-12十分簡單易懂的Java應(yīng)用程序性能調(diào)優(yōu)技巧分享
這篇文章主要介紹了十分簡單易懂的Java性能調(diào)優(yōu)技巧分享,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11剖析Java中HashMap數(shù)據(jù)結(jié)構(gòu)的源碼及其性能優(yōu)化
這篇文章主要介紹了Java中HashMap數(shù)據(jù)結(jié)構(gòu)的源碼及其性能優(yōu)化,文中以Java 8后HashMap的性能提升來討論了HashMap的一些優(yōu)化點(diǎn),需要的朋友可以參考下2016-05-05Java 滑動(dòng)窗口最大值的實(shí)現(xiàn)
這篇文章主要介紹了Java 滑動(dòng)窗口最大值,給定一個(gè)數(shù)組 nums,有一個(gè)大小為 k 的滑動(dòng)窗口從數(shù)組的最左側(cè)移動(dòng)到數(shù)組的最右側(cè)。感興趣的可以了解一下2021-05-05