天天看點

擷取字元長度的正确姿勢

public static void main(String[] args) throws UnsupportedEncodingException {
    String a="\uD864\uDD00";
    System.out.println(a.length()); //結果是2
    System.out.println(a.codePointCount(0, a.length())); //結果是1  這個才要正确姿勢
    System.out.println(a.getBytes("utf8").length);  //結果是4
}
           

這裡的\uD864\uDD00 ,對應的中文是參照https://segmentfault.com/q/1010000003757947

length 為什麼會不對呢,length其實是char數組的長度。char是16位,最多也就是能表示65536個字元,中文都不隻65536個,是以一個char是表示不了一個中文的。

更具體來說,char是 UTF-16 編碼的結果,UTF-16其實也是變長的,一個到兩個字元,有的時候會兩個char表示一個字元

有的人說可以用getBytes("utf8"),這個也是很不靠譜的,雖然多數中文的結果都是3,但是有少部分是4的。對于非中文更加可能是1或者2

[size=medium] 是以擷取字元個數應該用codePointCount。

這UTF-16的編碼規則,超出一個char的時候,是有特殊表示的,

具體地說保留了 D800-DFFF 共 2048 個位置:

D800-DBFF為高位 1024

DC00-DFFF 為地位 1024

1024*1024 = 一百萬 夠用了[/size]

[size=medium]可以看到codePointCount 的原理其實就是對于UTF-16的高地位(兩個char的情況)做了修正的[/size]