JavaRush /Java Blog /Random-IT /metodo charAt() in Java

metodo charAt() in Java

Pubblicato nel gruppo Random-IT
Esistono molte tecniche di base che utilizziamo regolarmente senza nemmeno pensarci. Bene, cosa succede se ci pensi e guardi come vengono implementati alcuni metodi apparentemente semplici? Penso che questo ci aiuterà ad avvicinarci di più a Java) charAt() in Java - 1Immaginiamo una situazione in cui dobbiamo estrarre un determinato carattere in una stringa. Come possiamo farlo in Java? Ad esempio, chiamando il Java String charAt. charAt()Parleremo del metodo nell'articolo di oggi.

Sintassi

char charAt(int index)restituisce il valore del carattere nell'indice specificato. L'indice varia da 0 a length()-1. Cioè, il primo charvalore della sequenza è in index 0, il successivo è in , index 1ecc., come nel caso dell'indicizzazione degli array.

Esempio

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 prima riga prende il primo carattere, la seconda il secondo e così via. Poiché not println, but viene utilizzato qui print, senza una nuova riga, otterremo il seguente output sulla console:

Java
Se charl'indice fornito è rappresentato come Unicode, il risultato del metodo java charAt()sarà il carattere che rappresenta questo Unicode:
System.out.println("J\u0061vaRush".charAt(1));
Uscita console:

a

Cosa c'è "sotto il cofano"

Come funziona, chiedi? charAt() in Java - 2Il fatto è che ogni oggetto Stringcontiene un array bytecon byte degli elementi di una determinata stringa:
private final byte[] value;
Ed ecco il metodo stesso chatAt:
public char charAt(int index) {
   if (isLatin1()) {
       return StringLatin1.charAt(value, index);
   } else {
       return StringUTF16.charAt(value, index);
   }
}
isLatin1- un flag che indica se la nostra stringa contiene solo caratteri latini oppure no. Ciò determina quale metodo verrà chiamato successivamente.

isLatin1 = vero

Se la stringa contiene solo caratteri latini, viene chiamato un metodo charAtdi classe statica StringLatin1:
public static char charAt(byte[] value, int index) {
   if (index < 0 || index >= value.length) {
       throw new StringIndexOutOfBoundsException(index);
   }
   return (char)(value[index] & 0xff);
}
Il primo passo è verificare che l'indice in ingresso sia maggiore o uguale a 0 e che non vada oltre l'array di byte interno e, in caso contrario, viene lanciata un'eccezione new StringIndexOutOfBoundsException(index). Se i controlli vengono superati, viene preso l'elemento di cui abbiamo bisogno. Alla fine vediamo:
  • &si estende per l'operazione binaria a bytebit per bit
  • 0xffnon fa altro che &richiede una discussione
  • (char)converte i dati da una tabella ASCII inchar

isLatin1 = falso

Se avessimo più di semplici caratteri latini, verrà utilizzata la classe StringUTF16e il suo metodo statico verrà chiamato:
public static char charAt(byte[] value, int index) {
   checkIndex(index, value);
   return getChar(value, index);
}
Che a sua volta chiama:
public static void checkIndex(int off, byte[] val) {
   String.checkIndex(off, length(val));
}
E delega ad un metodo statico String:
static void checkIndex(int index, int length) {
   if (index < 0 || index >= length) {
       throw new StringIndexOutOfBoundsException("index " + index +
                                                 ", length " + length);
   }
}
Qui infatti si verifica se l'indice è valido: ancora, se è positivo o zero, e se non è andato oltre i limiti dell'array. Ma in una classe StringUTF16di un metodo, charAtchiamare il secondo metodo sarà più 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));
}
Cominciamo ad analizzare cosa sta realmente accadendo qui. Il primo passo all'inizio del metodo è un altro controllo della validità dell'indice. Per capire cosa succede dopo, devi capire: quando un carattere non latino entra nell'array value, è rappresentato da due byte (due celle dell'array). Se abbiamo una stringa di due caratteri cirillici - "av", allora:
  • per 'a' questa è una coppia di byte: 48 e 4;
  • per 'in' - 50 e 4.
Cioè, se creiamo la stringa "av", avrà un array value- {48, 4, 50, 4} In realtà, questo metodo funziona con due celle dell'array value. Pertanto, il passo successivo è uno spostamento index <<= 1;per arrivare direttamente all'indice del primo byte del carattere desiderato nell'array value. Ora diciamo che abbiamo una stringa "абвг". Quindi l'array di valori sarà simile a questo: {48, 4, 49, 4, 50, 4, 51, 4}. Chiediamo il terzo elemento della stringa, quindi la rappresentazione binaria è 00000000 00000011. Se spostato di 1, otteniamo 00000000 00000110, cioè index = 6. Per rinfrescare le tue conoscenze sulle operazioni bit a bit, puoi leggere questo articolo . charAt() in Java - 4Vediamo anche alcune variabili: HI_BYTE_SHIFT in questo caso è 0. LO_BYTE_SHIFTin questo caso è 8. Nell'ultima riga di questo metodo:
  1. Un elemento viene preso dall'array di valori e spostato bit a bit di HI_BYTE_SHIFT, ovvero 0, aumentando index +1.

    Nell'esempio con la stringa "абвг", il sesto byte - 51 - rimarrebbe tale, ma contemporaneamente l'indice aumenterebbe a 7.

  2. Successivamente, l'elemento successivo dell'array viene preso e spostato bit per bit allo stesso modo, ma di LO_BYTE_SHIFT, cioè di 8 bit.

    E se avessimo il byte 4, che ha una rappresentazione binaria - 00000000 00000100, dopo lo spostamento di 8 bit avremo 00000100 00000000. Se è un numero intero - 1024.

  3. Successivamente, per questi due valori, segue l'operazione | (OR).

    E se avessimo i byte 51 e 1024, che nella rappresentazione binaria assomigliavano a 00000000 00110011 e 00000100 00000000, dopo l'operazione ORotterremo 00000100 00110011, che significa il numero 1075 nel sistema decimale.

    Bene, alla fine, il numero 1075 viene convertito nel tipo char e quando si converte int -> char viene utilizzata la tabella ASCII e in essa, sotto il numero 1075, c'è il carattere 'g'.

In realtà, è così che otteniamo "g" come risultato del metodo charAt()nella programmazione Java.
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION