溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java 中文字符按Unicode排序的實(shí)現(xiàn)方法

發(fā)布時(shí)間:2020-10-04 08:49:12 來源:腳本之家 閱讀:201 作者:robin 欄目:編程語言

遇到了一個(gè)對(duì)包含中文的字符串進(jìn)行排序的問題。要求按unicode編碼對(duì)字符串進(jìn)行排序。

測(cè)試字符串?dāng)?shù)組如下:

    String[] arr = {
        "1-測(cè)試",
        "1-編輯",
        "1-營銷",
        "1結(jié)束",
        "2-測(cè)試",
        "1-qt"
    };

按unicode排序的期望結(jié)果應(yīng)該是這樣的:

1-編輯, 1-測(cè)試, 1-營銷, 1-qt, 1結(jié)束, 2-測(cè)試

先按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-測(cè)試",
        "1-編輯",
        "1-營銷",
        "1結(jié)束",
        "2-測(cè)試",
        "1-qt"
    };
    Comparator<String> c = String::compareTo;
    Arrays.sort(arr, c);
    System.out.println(Arrays.toString(arr));
  }
}

結(jié)果如下:

[1-qt, 1-測(cè)試, 1-編輯, 1-營銷, 1結(jié)束, 2-測(cè)試]

可以看到中文字符不能按照拼音進(jìn)行排序。這時(shí)最直接的思路就是將中文字符轉(zhuǎn)為拼音后再進(jìn)行排序。但是要注意下,在這里面有個(gè)字符串不包含中文字符,這就容易導(dǎo)致順序混亂。

如下面這幾個(gè)字符串按拼音進(jìn)行排序順序如下:

1-編輯,1-測(cè)試,1-qt,1-營銷

可以看到字符串“1-qt”的位置出錯(cuò)了。 但是按拼音來說它的位置又是對(duì)的。這不能不說是一個(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-測(cè)試",
        "1-編輯",
        "1-營銷",
        "1結(jié)束",
        "2-測(cè)試",
        "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-測(cè)試, 1結(jié)束, 1-營銷, 2-測(cè)試]

結(jié)果看著好像還OK。但是停停、注意下、字符串“1結(jié)束”的位置好像比較奇妙,理想情況下它應(yīng)該在“1-營銷”的后面。

這里出問題的原因我沒有弄清楚。猜測(cè)著應(yīng)該是java在Chinese語法中將中劃線處理為空字符了。不過最根本的問題還是java對(duì)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-測(cè)試",
        "1-編輯",
        "1-營銷",
        "1結(jié)束",
        "2-測(cè)試",
        "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-測(cè)試, 1-營銷, 1-qt, 1結(jié)束, 2-測(cè)試]

可以看到是和預(yù)期一致的。

總結(jié)

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI