Java 碼點與代碼單元


1.先導概念

編碼格式簡介(ANSI、GBK、GB2312、UTF-8、GB18030和 UNICODE)

2.碼點和代碼單元

  • 碼點( code point) 是指與一個編碼表中的某個字符對應的代碼值。

    在 Unicode 標准中,碼點采用十六進制書寫,並加上前綴 U+, 例如 U+0041 就是拉丁字母 A 的碼點。Unicode 的碼點可以分成 17 個代碼級別( codeplane)。第一個代碼級別稱為基本的多語言級別( basicmultilingual plane ), 碼點從 U+0000 到 U+FFFF, 其中包括經典的 Unicode 代碼;其余的 16個級另丨〗碼點從 U+10000 到 U+10FFFF , 其中包括一些輔助字符(supplementary character)。

  • UTF-16 編碼采用不同長度的編碼表示所有 Unicode 碼點。在基本的多語言級別中,每個字符用 16 位表示,通常被稱為代碼單元( code unit),而輔助字符采用一對連續的代碼單元進行編碼。

    這樣構成的編碼值落人基本的多語言級別中空閑的 2048 字節內, 通常被稱為替代區域(surrogate area) [ U+D800 ~ U+DBFF 用於第一個代碼單兀,U+DC00 ~ U+DFFF 用於第二個代碼單元 ]。這樣設計十分巧妙,我們可以從中迅速地知道一個代碼單元是一個字符的編碼,還是一個輔助字符的第一或第二部分。例如,𝕆是八元數集(http://math.ucr.edu/home/baez/octonions) 的一個數學符號,碼點為 U+1D546, 編碼為兩個代碼單元U+D835 和 U+DD46。(關於編碼算法的具體描述見 http://en.wikipedia.org/wiki/UTF-l6 )

  • 在 Java 中,char 類型描述了 UTF-16 編碼中的一個代碼單元。

3.實例驗證

\uD835\uDD46實際上就是𝕆,只是在String里直接顯示為 16 進制

𝕆是作為一個輔助字符(兩個代碼單元),因而字符串hello\uD835\uDD46碼點為6,代碼單元為7

/**
 * \uD835\uDD46 = 𝕆
 * 輸出分別為:7、6
 */
private static void codePoints(){
    String sentence = "hello\uD835\uDD46";
    System.out.println(sentence.length());
    System.out.println(sentence.codePointCount(0,sentence.length()));
}

測試輸出對應的十六進制

/**
 * \uD835\uDD46 = 𝕆
 * 輸出分別為:d835
 *            dd46
 *            1d546
 */
private static void codePoints(){
    String sentence = "\uD835\uDD46";
    int length = sentence.length();
    for(int i = 0; i < length; i++){
        char c = sentence.charAt(i);
        System.out.println(Integer.toHexString(c));
    }
    System.out.println(Integer.toHexString(sentence.codePointAt(0)));
}

4.相關 String 類 API

  • char charAt ( int index )

    返回給定位置的代碼單元。除非對底層的代碼單元感興趣, 否則不需要調用這個方法。

  • int codePointAt ( int index ) jdk5.0后加入

    返回從給定位置開始的碼點。

  • int offsetByCodePoints( int startlndex, int cpCount) jdk5.0后加入

    返回從 startlndex 代碼點開始,位移 cpCount 后的碼點索引。

  • IntStream codePoints() jdk8后加入

    將這個字符串的碼點作為一個流返回。調用 toArray 將它們放在一個數組中

  • new String( int[ ] codePoints, int offset, int count) jdk5.0后加入

    用數組中從 offset 開始的 count 個碼點構造一個字符串。

  • int codePointCount( int startIndex, int endIndex ) jdk5.0后加入

    返回 startlndex 和 endludex-1之間的代碼點數量。沒有配成對的代用字符將計入代碼點。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM