java中代码点和代码单元的区别
阅读原文时间:2021年04月20日阅读:1

代码点:

代码点(code point)是指Unicode编码中的一个值,代表一个字符。有效范围从U+0000到U+10FFFF。其中U+0000到U+FFFF为基本字符,U+10000到U+10FFFF为增补字符。

代码单元:

代码单元(code unit):具体编码形式中的最小单元。对代码点进行编码得到的1或2个16位序列。其中基本字符的代码点直接用一个相同值的代码单元表示,增补字符的代码点用两个代码单元的进行编码,这个范围内没有数字用于表示字符,因此程序可以识别出当前字符是单单元的基本字符,还是双单元的增补字符。

在 Java 中一个 Unicode 字符是使用 UTF-16 编码的 char 进行表示的,也就是一个 char 只能表示 U+0000~U+FFFF 的 Unicode 基本字符(BMP)。因此在 Java 中需要表示 U+10000~U+10FFFF 的字符需要使用 一对代理字符进行表示,高代理字符的范围为 U+D800~U+DBFF,低代理字符的范围为 U+DC00~U+DFFF。比如表示 U+10400 的字符需要两个 char(U+D801, U+DC00)才能表示,这时的代码点长度为 1,而代码单元长度为 2。

High-Surrogate Code Unit. A 16-bit code unit in the range D80016 to DBFF16, used in UTF-16 as the leading code unit of a surrogate pair. Also known as a leading surrogate. (See definition D72 in Section 3.8, Surrogates.)

翻译:高代理代码单元:D800到DBFF范围内的16位代码单元,在UTF-16中用作代理对的前导代码单元。也称为主要代理

Low-Surrogate Code Unit. A 16-bit code unit in the range DC0016 to DFFF16, used in UTF-16 as the trailing code unit of a surrogate pair. Also known as a trailing surrogate. (See definition D74 in Section 3.8, Surrogates.)

翻译:低代理代码单元:在DC00到DFFF范围内的16位代码单元,在UTF-16中用作代理对的后面的代码单元。也称为后代理

代码点与代码单元:

一个代码单元为16位二进制,一个代码点为一个或两个16位二进制。即一个代码点可表示为一个代码单元或两个代码单元。

代码体现:

String.length()、AbstractStringBuilder.length() 方法返回的是代码单元的个数
String.codePointCount()、AbstractStringBuilder.codePointCount() 返回的是代码点的个数。
offsetByCodePoints() 方法返回的是从给定的index处偏移 codePointOffset 个代码点的索引。

@Test
public void testOffsetByCodePoints(){
    String str = "\u03C0\uD835\uDD6B";  //\uD835\uDD6B 代表两个代码单元代,一个代码点
    System.out.println(str.length());      //输出为 3
    System.out.println(str.codePointCount(0, str.length()));  //输出为 2
    System.out.println(str.offsetByCodePoints(0, 2)); //输出为 3
}

参考:
https://www.jianshu.com/p/c3a94294056a
https://blog.csdn.net/x_iya/article/details/53130117