JavaRush /Blog Java /Random-ES /método charAt() en Java

método charAt() en Java

Publicado en el grupo Random-ES
Hay muchas técnicas básicas que utilizamos habitualmente sin siquiera pensarlo. Bueno, ¿qué pasa si lo piensas y observas cómo se implementan algunos métodos aparentemente simples? Creo que esto nos ayudará a acercarnos un paso más a Java). charAt() en Java - 1Imaginemos una situación en la que necesitamos extraer un determinado carácter en alguna cadena. ¿Cómo podemos hacer esto en Java? Por ejemplo, llamando al Java String charAt. charAt()Hablaremos sobre el método en el artículo de hoy.

Sintaxis

char charAt(int index)devuelve el valor de carácter en el índice especificado. El índice oscila entre 0 y length()-1. Es decir, el primer charvalor de la secuencia está en index 0, el siguiente está en , index 1etc., como es el caso de la indexación de matrices.

Ejemplo

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));
}
La primera línea toma el primer carácter, la segunda línea toma el segundo y así sucesivamente. Dado que aquí no se usa printlnpero print, sin una nueva línea, obtendremos el siguiente resultado en la consola:

Java
Si charel índice dado se representa como Unicode, el resultado del método java charAt()será el carácter que representa este Unicode:
System.out.println("J\u0061vaRush".charAt(1));
Salida de consola:

a

¿Qué hay "debajo del capó"?

¿Cómo funciona, preguntas? charAt() en Java - 2El hecho es que cada objeto Stringcontiene una matriz bytecon bytes de los elementos de una cadena determinada:
private final byte[] value;
Y aquí está el método en sí chatAt:
public char charAt(int index) {
   if (isLatin1()) {
       return StringLatin1.charAt(value, index);
   } else {
       return StringUTF16.charAt(value, index);
   }
}
isLatin1- una bandera que indica si nuestra cadena contiene solo caracteres latinos o no. Esto determina qué método se llamará a continuación.

esLatin1 = verdadero

Si la cadena contiene sólo caracteres latinos, se llama a un método charAtde clase estática StringLatin1:
public static char charAt(byte[] value, int index) {
   if (index < 0 || index >= value.length) {
       throw new StringIndexOutOfBoundsException(index);
   }
   return (char)(value[index] & 0xff);
}
El primer paso es verificar que el índice entrante sea mayor o igual a 0, y que no vaya más allá del array de bytes interno, y si este no es el caso, entonces se lanza una excepción new StringIndexOutOfBoundsException(index). Si se pasan las comprobaciones, se toma el elemento que necesitamos. Al final vemos:
  • &se extiende para operación binaria a bytebit a bit
  • 0xffno hace nada más que &requiere un argumento
  • (char)convierte datos de una tabla ASCII achar

esLatin1 = falso

Si no tuviéramos solo caracteres latinos, se usará la clase StringUTF16y se llamará a su método estático:
public static char charAt(byte[] value, int index) {
   checkIndex(index, value);
   return getChar(value, index);
}
Que a su vez llama:
public static void checkIndex(int off, byte[] val) {
   String.checkIndex(off, length(val));
}
Y delega a un método estático String:
static void checkIndex(int index, int length) {
   if (index < 0 || index >= length) {
       throw new StringIndexOutOfBoundsException("index " + index +
                                                 ", length " + length);
   }
}
Aquí, de hecho, se comprueba si el índice es válido: nuevamente, si es positivo o cero y si no ha sobrepasado los límites de la matriz. Pero en una clase StringUTF16en un método, charAtllamar al segundo método será más interesante:
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));
}
Comencemos a analizar lo que realmente está sucediendo aquí. El primer paso al comienzo del método es otra verificación de la validez del índice. Para comprender lo que sucede a continuación, debe comprender: cuando un carácter no latino ingresa a la matriz value, se representa mediante dos bytes (dos celdas de la matriz). Si tenemos una cadena de dos caracteres cirílicos - "av", entonces:
  • para 'a' es un par de bytes: 48 y 4;
  • para 'en' - 50 y 4.
Es decir, si creamos la cadena “av”, tendrá una matriz value- {48, 4, 50, 4} En realidad, este método funciona con dos celdas de una matriz value. Por lo tanto, el siguiente paso es un desplazamiento index <<= 1;para llegar directamente al índice del primer byte del carácter deseado en la matriz value. Ahora digamos que tenemos una cadena "абвг". Entonces la matriz de valores se verá así: {48, 4, 49, 4, 50, 4, 51, 4}. Solicitamos el tercer elemento de la cadena y luego la representación binaria es 00000000 00000011. Cuando lo desplazamos en 1, obtenemos 00000000 00000110, es decir index = 6. Para actualizar sus conocimientos sobre operaciones bit a bit, puede leer este artículo . charAt() en Java - 4También vemos algunas variables: HI_BYTE_SHIFT en este caso es 0. LO_BYTE_SHIFTen este caso es 8. En la última línea de este método:
  1. Se toma un elemento de la matriz de valores y se desplaza bit a bit en HI_BYTE_SHIFT, es decir, 0, mientras se aumenta index +1.

    En el ejemplo con la cadena "абвг", el sexto byte (51) permanecería así, pero al mismo tiempo el índice aumentaría a 7.

  2. Después de esto, se toma el siguiente elemento de la matriz y se desplaza bit a bit de la misma manera, pero con LO_BYTE_SHIFT, es decir, 8 bits.

    Y si tuviéramos el byte 4, que tiene una representación binaria: 00000000 00000100, luego de cambiar 8 bits tendremos 00000100 00000000. Si es un número entero, 1024.

  3. A continuación, para estos dos valores, sigue la operación | (OR).

    Y si tuviéramos los bytes 51 y 1024, que en representación binaria se parecían a 00000000 00110011 y 00000100 00000000, luego de la operación ORobtendremos 00000100 00110011, lo que significa el número 1075 en el sistema decimal.

    Bueno, al final, el número 1075 se convierte al tipo char, y al convertir int -> char se usa la tabla ASCII, y en ella, debajo del número 1075, está el carácter 'g'.

En realidad, así es como obtenemos 'g' como resultado del método charAt()en programación Java.
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION