¿Qué es un “par suplente” en Java?

Estaba leyendo la documentación de StringBuffer , en particular, el método reverse () . Esa documentación menciona algo sobre pares de sustitución . ¿Qué es un par suplente en este contexto? ¿Y qué son sustitutos bajos y altos ?

El término “par suplente” se refiere a un medio de encoding de caracteres Unicode con altos puntos de código en el esquema de encoding UTF-16.

En la encoding de caracteres Unicode, los caracteres se asignan a valores entre 0x0 y 0x10FFFF.

Internamente, Java usa el esquema de encoding UTF-16 para almacenar cadenas de texto Unicode. En UTF-16, se usan unidades de código de 16 bits (dos bytes). Como 16 bits solo pueden contener el rango de caracteres de 0x0 a 0xFFFF, se usa cierta complejidad adicional para almacenar valores por encima de este rango (0x10000 a 0x10FFFF). Esto se hace usando pares de unidades de código conocidas como sustitutos.

Las unidades de código sustituto están en dos rangos conocidos como “sustitutos altos” y “sustitutos bajos”, dependiendo de si están permitidos al principio o al final de la secuencia de dos unidades de código.

Lo que esa documentación está diciendo es que las cadenas UTF-16 inválidas pueden volverse válidas después de llamar al método reverse ya que podrían ser las reversiones de las cadenas válidas. Un par suplente (discutido aquí ) es un par de valores de 16 bits en UTF-16 que codifican un único punto de código Unicode; los sustitutos bajos y altos son las dos mitades de esa encoding.

Las primeras versiones de Java representaban caracteres Unicode utilizando el tipo de datos char de 16 bits. Este diseño tenía sentido en ese momento, porque todos los caracteres Unicode tenían valores inferiores a 65.535 (0xFFFF) y podían representarse en 16 bits. Más tarde, sin embargo, Unicode aumentó el valor máximo a 1,114,111 (0x10FFFF). Como los valores de 16 bits eran demasiado pequeños para representar todos los caracteres Unicode en la versión 3.1 de Unicode, se adoptaron valores de 32 bits, llamados puntos de código, para el esquema de encoding UTF-32. Pero los valores de 16 bits se prefieren a los valores de 32 bits para un uso eficiente de la memoria, por lo que Unicode introdujo un nuevo diseño para permitir el uso continuo de los valores de 16 bits. Este diseño, adoptado en el esquema de encoding UTF-16, asigna 1.024 valores a sustitutos altos de 16 bits (en el rango U + D800 a U + DBFF) y otros 1.024 valores a sustitutos bajos de 16 bits (en el rango U + DC00 a U + DFFF). Utiliza un subrogado alto seguido de un sustituto bajo, un par sustituto, para representar (el producto de 1,024 y 1,024) valores de 1,048,576 (0x100000) entre 65,536 (0x10000) y 1,114,111 (0x10FFFF).

Los pares sustituidos se refieren a la forma en que UTF-16 codifica ciertos caracteres, consulte http://en.wikipedia.org/wiki/UTF-16/UCS-2#Code_points_U.2B10000..U.2B10FFFF

Un par suplente es dos ‘unidades de código’ en UTF-16 que componen un ‘punto de código’. La documentación de Java indica que estos ‘puntos de código’ seguirán siendo válidos, con sus ‘unidades de código’ ordenadas correctamente, después del reverso. Además establece que dos unidades de código sustituto no emparejadas pueden invertirse y formar un par sustituto válido. Lo que significa que si hay unidades de código sin emparejar, ¡existe la posibilidad de que el reverso del reverso no sea el mismo!

Sin embargo, tenga en cuenta que la documentación no dice nada acerca de Graphemes, que son múltiples puntos de código combinados. Lo que significa que e y el acento que lo acompaña todavía pueden cambiarse, colocando así el acento antes de la e. Lo que significa que si hay otra vocal antes de la e, puede obtener el acento que estaba en la e.

¡Ay!