5分でコードポイントとコードユニットを理解します


1 Unicode
Unicodeは通称万国コードと呼ばれ、1980年代に統一作業が開始されたとき、2バイトのコード幅は世界の様々な言語のすべての文字を符号化するのに十分であり、将来の拡張に十分な空間があると考えられていた.1991年にUnicode 1が発表された.0は、当時65536(2バイト)個のコード値の半分未満の部分しか占めていなかった.
奈何中華文化は博大で奥深く、Unicode文字は65536文字を超えた.現在、16ビットのcharタイプはすべてのUnicode文字を記述することを満たすことができません.
2コードポイント(Code Point)
符号点とは、1つの符号化テーブルのある文字に対応する符号値を指す.Unicode規格では、符号点は16進数で書かれ、プレフィックスU+が付加されている.例えば、U+0041はアルファベットAの符号点である.Unicodeの符号点は17個の符号平面に分けることができる.第1のコードプレーンは、U+0000からU+FFFFまでのコードポイントを含む古典的なUnicodeコードを含む基本的な多言語プレーンと呼ばれ、残りの16のプレーンのコードポイントは、U+10000からU+10 FFFFFFまでであり、補助文字を含む.
クラスはASCIIコードに比べて、コードポイントは文字に対応するASCII値のようなものです.
3コードユニット(Code Unit)
UTF-16符号化は全Unicode符号化を異なる長さの符号化で表す.基本多言語平面では、各文字は16ビットで表され、コードユニットと呼ばれる.補助文字は、一対の連続するコードユニットに符号化される.このような符号化ペアによって表される各値は、基本的な多言語平面において使用されていない2048の値の範囲内にあり、通常、代替領域と呼ばれる.このような設計は非常に巧みで、1つのコードユニットのときの1つの文字の符号化、または補助文字の第1または第2の部分を迅速に知ることができる.
すなわち,最初のコード平面では,各値を完全に使用するのではなく,いくつかの値区間が残っている.では、これらの使用されていない値区間を組み合わせて、より大きな符号点を表すことができます.なぜなら、私たちが使用できるビット数は16ビットではなく、16ビットよりも長いからです.具体的にどのように使用するかは,符号化アルゴリズムにかかわる.
4実用化
Javaでは、charタイプはUTF-16符号化のコード単位を記述する.
UTF-16コードユニットを処理する必要がない限り、プログラムでcharタイプを使用しないことを強くお勧めします.文字列を抽象データ型として扱うのが望ましい
5認知を破る
まずコードを見てみましょう
/**
 * @Author Panda
 * @Date 2020/6/15 17:11
 * @Version 1.0
 */
public class CodePoint {
    public static void main(String[] args) {
        String s = "Unicode";

        System.out.println("0       "+s.charAt(0));  //0       U
        System.out.println("0     " + s.codePointAt(0));  //0     85

        System.out.println("      " + s.length());  //      7
        System.out.println("    " + s.codePointCount(0,s.length()));  //    7
    }
}


この例の出力は私たちの予想通りに見えます
コードを見てみましょう
/**
 * @Author Panda
 * @Date 2020/6/15 17:11
 * @Version 1.0
 */
public class CodePoint {
    public static void main(String[] args) {
        String s = "";

        System.out.println("0       "+s.charAt(0));  //0       ?
        System.out.println("0     " + s.codePointAt(0));  //0     127804

        System.out.println("      " + s.length());  //      2
        System.out.println("    " + s.codePointCount(0,s.length()));  //    1
    }
}


この例は、私たちの認識を少し破った.s.charAt(0)の出力はなんと?s.length()の出力はなんと2?すべては少し予想外に見えた.
sの符号点は127804(1 F 33 C)であるため、基本多言語平面ではなく、つまり1つの符号単位では表現できないので、2つの符号単位で表さなければならない.s.length()は符号点数ではなく符号単位数を返すが、私たちがよく使う文字はすべて基本多言語平面に属し、したがって、このとき、1つのコードユニットは1つのコードポイントに対応するので、s.length()の戻り値は、私たちが認識している文字列の長さである.