java字符串排序_对字符串排序持一种宽容的心态
在Java中一涉及中文處理就會冒出很多問題來,其中排序也是一個讓人頭疼的課題,我們來看下面的代碼:
上面的代碼定義一個數(shù)組,然后進(jìn)行升序排序,我們期望的結(jié)果是按照拼音升序排列,即為李四、王五、張三,但是結(jié)果卻不是這樣的:
這是按照什么排序的呀,非?;靵y!我們知道Arrays工具類的默認(rèn)排序是通過數(shù)組元素的compareTo方法來進(jìn)行比較的,那我們來看String類的compareTo的主要實(shí)現(xiàn):
上面的代碼先取得字符串的字符數(shù)組,然后一個一個地比較大小,注意這里是字符比較(減號操作符),也就是UNICODE碼值的比較,查一下UNICODE代碼表,“張”的碼值是5F20,而“李”是674E,這樣一看,“張”排在“李”的前面也就很正確了—但這明顯與我們的意圖沖突了。這一點(diǎn)在JDK文檔中也有說明:對于非英文的String排序可能會出現(xiàn)不準(zhǔn)確的情況。那該如何解決這個問題呢?Java推薦使用
Collator類進(jìn)行排序,那好,我們把代碼修改一下:
輸出結(jié)果如下:
這確實(shí)是我們期望的結(jié)果,應(yīng)該舉杯慶賀了吧!但是且慢,中國的漢字博大精深,Java是否都能精確的排序呢?最主要的一點(diǎn)是漢字中有象形文字,音形分離,是不是每個漢字都能按照拼音的順序排列好呢?我們寫一個復(fù)雜的漢字來看看:
三個?!盃摹弊xbēn,三個金“鑫”讀xīn,這兩個字經(jīng)常出現(xiàn)在飯店和商店的名稱上,我們來看排序的輸出結(jié)果:
輸出結(jié)果又亂了!不要責(zé)怪Java,它已經(jīng)盡量為我們考慮了,只是因?yàn)槲覀兊臐h字文化太博大精深了,要做好這個排序確實(shí)有點(diǎn)難為它。更深層次的原因是Java使用的是UNICODE編碼,而中文UNICODE字符集是來源于GB18030的,GB18030又是從GB2312發(fā)展起來,GB2312是一個包含了7000多個字符的字符集,它是按照拼音排序,并且是連續(xù)的,之后的GBK、GB18030都是在其基礎(chǔ)上擴(kuò)充出來的,所以要讓它們完整排序也就難上加難了。
如果是排序?qū)ο笫墙?jīng)常使用的漢字,使用Collator類排序完全可以滿足我們的要求,畢竟GB2312已經(jīng)包含了大部分的漢字,如果需要嚴(yán)格排序,則要使用一些開源項(xiàng)目來自己實(shí)現(xiàn)了,比如pinyin4j可以把漢字轉(zhuǎn)換為拼音,然后我們自己來實(shí)現(xiàn)排序算法,不過此時你也會發(fā)現(xiàn)要考慮諸如算法、同音字、多音字等眾多問題。
本文參考自:《編寫高質(zhì)量代碼:改善java程序的151個建議》
作者:秦小波
聲明:本文只供學(xué)習(xí)使用,未涉及任何商業(yè)利益,如有侵權(quán),立刪。
支持作者贊賞就不用啦,生活都不易,右下角的“在看/贊”點(diǎn)一下,如果感覺文章不錯,記得分享到朋友圈讓更多人知道!
總結(jié)
以上是生活随笔為你收集整理的java字符串排序_对字符串排序持一种宽容的心态的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 信号与系统—傅里叶级数
- 下一篇: IO流复制图片