JavaRush /Blogue Java /Random-PT /Método charAt() em Java

Método charAt() em Java

Publicado no grupo Random-PT
Existem muitas técnicas básicas que usamos regularmente, mesmo sem pensar nisso. Bem, e se você pensar sobre isso e observar como alguns métodos aparentemente simples são implementados? Acho que isso nos ajudará a chegar um passo mais perto do Java. charAt() em Java - 1Vamos imaginar uma situação em que precisamos extrair um determinado caractere de alguma string. Como podemos fazer isso em Java? Por exemplo, chamando o Java String charAt. charAt()Falaremos sobre o método no artigo de hoje.

Sintaxe

char charAt(int index)retorna o valor char no índice especificado. O índice varia de 0 a length()-1. Ou seja, o primeiro charvalor da sequência está em index 0, o próximo está em , index 1etc., como é o caso da indexação de array.

Exemplo

public static void main(String[] args) {
   System.out.print("JavaRush".charAt(0));
   System.out.print("JavaRush".charAt(1));
   System.out.print("JavaRush".charAt(2));
   System.out.print("JavaRush".charAt(3));
}
A primeira linha leva o primeiro caractere, a segunda linha leva o segundo e assim por diante. Como not println, mas é usado aqui print, sem uma nova linha, obteremos a seguinte saída no console:

Java
Se charo índice fornecido for representado como Unicode, o resultado do método java charAt()será o caractere que representa este Unicode:
System.out.println("J\u0061vaRush".charAt(1));
Saída do console:

a

O que está "sob o capô"

Como isso funciona, você pergunta? charAt() em Java - 2O fato é que cada objeto Stringcontém um array bytecom bytes dos elementos de uma determinada linha:
private final byte[] value;
E aqui está o método em si chatAt:
public char charAt(int index) {
   if (isLatin1()) {
       return StringLatin1.charAt(value, index);
   } else {
       return StringUTF16.charAt(value, index);
   }
}
isLatin1- um sinalizador que indica se nossa string contém apenas caracteres latinos ou não. Isso determina qual método será chamado a seguir.

isLatin1 = verdadeiro

Se a string contiver apenas caracteres latinos, um método charAtde classe estático será chamado StringLatin1:
public static char charAt(byte[] value, int index) {
   if (index < 0 || index >= value.length) {
       throw new StringIndexOutOfBoundsException(index);
   }
   return (char)(value[index] & 0xff);
}
O primeiro passo é verificar se o índice de entrada é maior ou igual a 0, e se não ultrapassa o array de bytes interno, e caso não seja o caso, então é lançada uma exceção new StringIndexOutOfBoundsException(index). Se as verificações forem aprovadas, o elemento que precisamos será obtido. No final vemos:
  • &estende a operação binária para bytebit a bit
  • 0xffnão faz nada, mas &requer um argumento
  • (char)converte dados de uma tabela ASCII parachar

isLatin1 = falso

Se não tivéssemos apenas caracteres latinos, a classe será utilizada StringUTF16e seu método estático será chamado:
public static char charAt(byte[] value, int index) {
   checkIndex(index, value);
   return getChar(value, index);
}
Que por sua vez chama:
public static void checkIndex(int off, byte[] val) {
   String.checkIndex(off, length(val));
}
E ele delega para um método estático String:
static void checkIndex(int index, int length) {
   if (index < 0 || index >= length) {
       throw new StringIndexOutOfBoundsException("index " + index +
                                                 ", length " + length);
   }
}
Aqui, de fato, é feita uma verificação para ver se o índice é válido: novamente, se é positivo ou zero, e se não ultrapassou os limites do array. Mas em uma classe StringUTF16de método, charAtchamar o segundo método será mais interessante:
static char getChar(byte[] val, int index) {
   assert index >= 0 && index < length(val) : "Trusted caller missed bounds check";
   index <<= 1;
   return (char)(((val[index++] & 0xff) << HI_BYTE_SHIFT) |
                 ((val[index]   & 0xff) << LO_BYTE_SHIFT));
}
Vamos começar a analisar o que realmente está acontecendo aqui. A primeira etapa no início do método é outra verificação da validade do índice. Para entender o que acontece a seguir, é preciso entender: quando um caractere não latino entra no array value, ele é representado por dois bytes (duas células do array). Se tivermos uma sequência de dois caracteres cirílicos - “av”, então:
  • para 'a' é um par de bytes - 48 e 4;
  • para 'in' - 50 e 4.
Ou seja, se criarmos a string “av”, ela terá um array value- {48, 4, 50, 4} Na verdade, este método funciona com duas células do array value. Portanto, o próximo passo é um deslocamento index <<= 1;para chegar diretamente ao índice do primeiro byte do caractere desejado no array value. Agora digamos que temos uma string "абвг". Então a matriz de valores ficará assim: {48, 4, 49, 4, 50, 4, 51, 4}. Pedimos o terceiro elemento da string e então a representação binária é 00000000 00000011. Quando deslocado por 1, obtemos 00000000 00000110, ou seja index = 6. Para atualizar seu conhecimento sobre operações bit a bit, você pode ler este artigo . charAt() em Java - 4Vemos também algumas variáveis: HI_BYTE_SHIFT neste caso é 0. LO_BYTE_SHIFTneste caso é 8. Na última linha deste método:
  1. Um elemento é retirado da matriz de valores e deslocado bit a bit por HI_BYTE_SHIFT, ou seja, 0, enquanto aumenta index +1.

    No exemplo com a string "абвг", o sexto byte – 51 – permaneceria assim, mas ao mesmo tempo o índice aumenta para 7.

  2. Depois disso, o próximo elemento do array é obtido e deslocado bit a bit da mesma forma, mas por LO_BYTE_SHIFT, ou seja, por 8 bits.

    E se tivéssemos o byte 4, que tem uma representação binária - 00000000 00000100, depois de deslocar 8 bits teremos 00000100 00000000. Se for um número inteiro - 1024.

  3. A seguir, para estes dois valores, segue a operação | (OR).

    E se tivéssemos os bytes 51 e 1024, que em representação binária se pareciam com 00000000 00110011 e 00000100 00000000, depois da operação ORobteríamos 00000100 00110011, que significa o número 1075 no sistema decimal.

    Bom, no final, o número 1075 é convertido para o tipo char, e ao converter int -> char, é utilizada a tabela ASCII, e nela, sob o número 1075, está o caractere 'g'.

Na verdade, é assim que obtemos 'g' como resultado do método charAt()na programação Java.
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION