我正在阅读 StringBuffer的文档,特别是 反向()方法。该文档提到了关于 代理人配对的一些内容。在这种情况下,什么是代理对?什么是 低和 很高代理?
StringBuffer
代理项对指的是 UTF-16对特定字符进行编码的方式,请参见 http://en.wikipedia.org/wiki/UTF-16/UCS-2#Code_points_U.2B10000..U.2B10FFFF
文档的意思是,无效的 UTF-16字符串在调用 reverse方法之后可能会变成有效的,因为它们可能是有效字符串的反面。代理对(我们讨论过 给你)是 UTF-16中一对编码单个 Unicode字符的16位值,低代理和高代理是编码的两部分。
reverse
术语“代理对”是指在 UTF-16编码模式中使用高编码点对 Unicode 字符进行编码的方法。
在 Unicode 字符编码中,字符被映射到0x0到0x10FFFF 之间的值。
在内部,Java 使用 UTF-16编码模式来存储 Unicode 文本的字符串。在 UTF-16中,使用16位(两字节)代码单元。由于16位只能包含从0x0到0xFFFF 的字符范围,所以使用一些额外的复杂性来存储这个范围(0x10000到0x10FFFF)以上的值。这是通过使用称为代理的代码单元对来完成的。
代理代码单元在两个范围内,即“高代理”和“低代理”,这取决于在两个代码单元序列的开始或结束处是否允许它们。
代理对是 UTF-16中的两个“代码单元”,组成一个“代码点”。Java 文档声明这些“代码点”仍然有效,它们的“代码单元”在反过来之后排序正确。它进一步指出,两个不成对的代理代码单元可以相反,并形成一个有效的代理代理对。这意味着,如果有不成对的代码单位,那么有一个机会,反向可能是不一样的!
但是请注意,文档中没有提到 Graphemes ——它是多个代码点的组合。这意味着 e 和随之而来的重音仍然可能被转换,因此把重音放在 e 之前,这意味着如果在 e 之前有另一个元音,它可能会得到 e 上的重音。
哎呀!
早期的 Java 版本使用16位字符数据类型表示 Unicode 字符。这种设计在当时是有意义的,因为所有 Unicode 字符的值都小于65,535(0xFFFF) ,并且可以用16位来表示。但是,后来 Unicode 将最大值增加到1,114,111(0x10FFFF)。由于16位值太小,无法表示 Unicode 3.1版中的所有 Unicode 字符,因此 UTF-32编码方案采用了32位值(称为编码点)。 但是为了有效地使用内存,16位值比32位值更受欢迎,因此 Unicode 引入了一种新的设计,允许继续使用16位值。这种设计采用了 UTF-16编码方案,将1024个值分配给16位高代理(U + D800到 U + DBFF) ,另外1024个值分配给16位低代理(U + D00到 U + DFFF)。它使用一个高代理项后跟一个低代理项ーー一个代理项对ーー来表示65,536(0x10000)和1,114,111(0x10FFFF)之间的(1,024和1,024的乘积)1,048,576(0x100000)值。
从 这个帖子中为上面的答案添加一些更多的信息。
经过 Java-12测试,应该可以在5以上的所有 Java 版本中工作。
正如这里提到的: https://stackoverflow.com/a/47505451/2987755, 任何一个字符(其 Unicode 高于 U + FFFF)表示为代理对,Java 将其存储为一对 char 值,即单个 Unicode字符表示为两个相邻的 Java 字符。 正如我们在下面的例子中看到的。 1. 长度:
"🌉".length() //2, Expectations was it should return 1 "🌉".codePointCount(0,"🌉".length()) //1, To get the number of Unicode characters in a Java String
2. 平等: 使用 Unicode \ud83c\udf09将“”表示为 String,并检查是否相等。
\ud83c\udf09
"🌉".equals("\ud83c\udf09") // true
Java 不支持 UTF-32
"🌉".equals("\u1F309") // false
你可以把 Unicode字符转换成 Java 字符串
"🌉".equals(new String(Character.toChars(0x0001F309))) //true
Substring ()不考虑补充字符
"🌉🌐".substring(0,1) //"?" "🌉🌐".substring(0,2) //"🌉" "🌉🌐".substring(0,4) //"🌉🌐"
为了解决这个问题,我们可以使用 String.offsetByCodePoints(int index, int codePointOffset)
String.offsetByCodePoints(int index, int codePointOffset)
"🌉🌐".substring(0,"🌉🌐".offsetByCodePoints(0,1) // "🌉" "🌉🌐".substring(2,"🌉🌐".offsetByCodePoints(1,2)) // "🌐"
5. 使用 断路器迭代 Unicode 字符串 6. 使用 Unicode 对字符串进行排序 7. 不应使用字符的 toUpperCase()、 toLowerCase()方法,而应使用特定语言环境的字符串大小写。 8.Character.isLetter(char ch)不支持,更好地使用 Character.isLetter(int codePoint),对于每个 methodName(char ch)方法在字符类将有类型的 methodName(int codePoint),可以处理补充字符。 在 String.getBytes()中指定字符集,从 Bytes 转换为 String,InputStreamReader,OutputStreamWriter
toUpperCase()
toLowerCase()
Character.isLetter(char ch)
Character.isLetter(int codePoint)
methodName(char ch)
methodName(int codePoint)
String.getBytes()
InputStreamReader
OutputStreamWriter
参考: Https://coolsymbol.com/emojis/emoji-for-copy-and-paste.html#objects Https://www.online-toolz.com/tools/text-unicode-entities-convertor.php Https://www.ibm.com/developerworks/library/j-unicode/index.html Https://www.oracle.com/technetwork/articles/javaee/supplementary-142654.html
更多关于示例 图1 图2的信息 其他值得探索的术语: 正常化,< a href = “ https://en.wikipedia.org/wiki/Bi-direct _ text”rel = “ noReferrer”> BiDi
小小的序言
Unicode 表示代码点。根据 Unicode 标准,每个代码点可以编码为8位、16位或32位块。
在 Version 3.1之前,主要使用的是8位编码(称为 UTF-8)和16位编码(称为 UCS-2或“通用字符集以2个八位字节编码”)。UTF-8将 Unicode 点编码为一个1字节的块序列,而 UCS-2总是占用2字节:
A = 41 -一个带有 UTF-8的8位块 A = 0041 -一个带 UCS-2的16位块 Ω = CEA9 -两个带 UTF-8的8位块 Ω = 03A9 -一个带 UCS-2的16位块
问题
该联盟认为,16位将足以涵盖任何人类可读的语言,这使得 2 ^ 16 = 65536可能的代码值。这是真正的平面0,也称为 BMP 或基本多语言平面,其中包括55,445的65536个代码点今天。BMP 几乎涵盖了世界上所有的人类语言,包括中日韩符号(CJK)。
随着时间的推移,新的亚洲字符集被添加进来,仅中文符号就占据了超过70,000分。现在,甚至有 表情符号点数作为标准的一部分。新增16个“额外”飞机。UCS-2房间不足以覆盖任何比飞机 -0大的东西。
Unicode 决定
随着这些变化,BMP 在 UTF-16中被覆盖了1个16位的块,而所有的“补充字符”都被 代理机器人覆盖,每个 代理机器人呈现2个16位的块,总共1024x1024 = 1048576点。
高代理项优先于低代理项 。任何偏离此规则的行为都被认为是错误的编码。例如,没有对的代理项是不正确的,位于高代理项之前的低代理项是不正确的。
,‘ MUSAL SYMBOL G CLEF’,以 UTF-16编码,作为一对代理人0xD8340xDD1E (2乘2字节) , 0xF00x9D 0x840x9E (4 × 1字节) , 以 UTF-32为0x0001D11E (1乘4字节)。
目前的情况
许多历史细节都被压制下去了。 最新的 Unicode 标准可以在 < a href = “ http://www.Unicode.org/version/last”rel = “ norefrer”> http://www.Unicode.org/versions/latest 找到