Unicode 代码点数组转换为字符串并返回更改

Unicode code points array is converted to String and back with changes

定义了Unicode代码点的数组是:

int[] unicodeDefinedCodePoints = IntStream
            .rangeClosed(Character.MIN_CODE_POINT, Character.MAX_CODE_POINT)
            .filter(Character::isDefined)
            .toArray();

让我们将其转换为字符串并返回代码点:

int[] unicodeDefinedCodePointsAfterTransformation =
            new String(unicodeDefinedCodePoints, 0, unicodeDefinedCodePoints.length)
                .codePoints()
                .toArray();

我希望得到相同的数组,但是

  1. 转换后的数组不包含码位56319和56320
  2. 转换后代码点1113088重复

以上代码点的代码均为十进制。

使用的 Java 版本是:

openjdk version "1.8.0_275"
OpenJDK Runtime Environment (IcedTea 3.17.1) (build 1.8.0_275-b01 suse-1.1-x86_64)
OpenJDK 64-Bit Server VM (build 25.275-b01, mixed mode)

有什么想法吗?

谢谢。

没有明确的答案

  • 56319为U+DBFF,私用高代理,最后
  • 56320是U+DC00,低代理,第一
  • 1113088是U+10FC00,无效字符。

可能是先处理高代理项,然后处理低代理项。而无效字符当然是单例黑洞;失败时的替换字符。

对于surrogate pair,就递减走,或者做一个码点的两个String。

int[] unicodeDefinedCodePoints = IntStream
        .rangeClosed(-Character.MAX_CODE_POINT, -Character.MIN_CODE_POINT)
        .map(Math::abs)
        .filter(Character::isValidCodePoint)
        .toArray();

我认为 isDefined 和 isValidCodePoint 之间没有区别,但后者更清楚。

有效的 Unicode 代码点是 0 (MIN_CODE_POINT) 和 1114111 (MAX_CODE_POINT) 之间的代码点。但是,55296 (MIN_SURROGATE) 和 57343 (MAX_SURROGATE) 之间的代码点保留给 highSurrogates 和 lowSurrogates,它们成对表示代码点介于 65536 和 1114111 之间的字符,因为 65535 是最大的数字可以存储为 2 字节的字符。 要获取所有有效 unicode 代码点的数组,您必须排除代理项,如下所示。

int[] unicodeDefinedCodePoints = IntStream
     .rangeClosed(Character.MIN_CODE_POINT, Character.MAX_CODE_POINT)
     .filter((i) -> i < Character.MIN_SURROGATE || i > Character.MAX_SURROGATE)
     .toArray();

数组应包括所有 1112064 个有效代码点。