O que é um “par substituto” em Java?

Eu estava lendo a documentação para StringBuffer , em particular o método reverse () . Essa documentação menciona algo sobre pares substitutos . O que é um par substituto neste contexto? E quais são substitutos baixos e altos ?

   

    O termo “par substituto” refere-se a um meio de codificar caracteres Unicode com altos pontos de código no esquema de codificação UTF-16.

    Na codificação de caracteres Unicode, os caracteres são mapeados para valores entre 0x0 e 0x10FFFF.

    Internamente, o Java usa o esquema de codificação UTF-16 para armazenar strings de texto Unicode. Em UTF-16, unidades de código de 16 bits (dois bytes) são usadas. Como 16 bits podem conter apenas o intervalo de caracteres de 0x0 a 0xFFFF, alguma complexidade adicional é usada para armazenar valores acima desse intervalo (0x10000 a 0x10FFFF). Isso é feito usando pares de unidades de código conhecidas como substitutos.

    As unidades de código substitutas estão em dois intervalos conhecidos como “altos substitutos” e “baixos substitutos”, dependendo de serem permitidos no início ou no final da sequência de duas unidades de código.

    O que essa documentação está dizendo é que as strings UTF-16 inválidas podem se tornar válidas depois de chamar o método reverse , já que elas podem ser as reversões de strings válidas. Um par substituto (discutido aqui ) é um par de valores de 16 bits em UTF-16 que codificam um único ponto de código Unicode; os substitutos baixo e alto são as duas metades dessa codificação.

    As primeiras versões do Java representavam caracteres Unicode usando o tipo de dados char de 16 bits. Esse design fazia sentido na época, porque todos os caracteres Unicode tinham valores menores que 65.535 (0xFFFF) e podiam ser representados em 16 bits. Mais tarde, no entanto, Unicode aumentou o valor máximo para 1,114,111 (0x10FFFF). Como os valores de 16 bits eram muito pequenos para representar todos os caracteres Unicode na versão 3.1 do Unicode, os valores de 32 bits – chamados de pontos de código – foram adotados para o esquema de codificação UTF-32. Mas os valores de 16 bits são preferidos em relação aos valores de 32 bits para uso eficiente da memory, portanto, o Unicode introduziu um novo design para permitir o uso contínuo de valores de 16 bits. Esse design, adotado no esquema de codificação UTF-16, atribui 1.024 valores a substitutos altos de 16 bits (no intervalo U + D800 a U + DBFF) e outros 1.024 valores a substitutos baixos de 16 bits (no intervalo U + DC00 para U + DFFF). Ele usa um substituto alto seguido por um substituto baixo – um par substituto – para representar (o produto de 1.024 e 1.024) valores 1.048.576 (0x100000) entre 65.536 (0x10000) e 1.114.111 (0x10FFFF).

    Pares substitutos referem-se ao modo de codificação de certos caracteres do UTF-16, veja http://en.wikipedia.org/wiki/UTF-16/UCS-2#Code_points_U.2B10000..U.2B10FFFF

    Um par substituto é duas ‘unidades de código’ em UTF-16 que compõem um ‘ponto de código’. A documentação do Java está afirmando que esses ‘pontos de código’ ainda serão válidos, com suas ‘unidades de código’ ordenadas corretamente, após o reverso. Afirma ainda que duas unidades de código substitutas desemparelhadas podem ser invertidas e formar um par substituto válido. O que significa que, se houver unidades de código desemparelhadas, existe a chance de que o reverso do verso não seja o mesmo!

    Observe, porém, que a documentação não diz nada sobre Graphemes – que são múltiplos códigos combinados. O que significa ee o acento que vai junto com ele ainda pode ser trocado, colocando assim o acento antes do e. O que significa que se houver outra vogal antes da e pode obter o acento que estava no e.

    Yikes!