Un array è una lista a dimensione fissa
Un array in Java contiene un numero fisso di valori dello stesso tipo, disposti in ordine e accessibili per posizione. "Fisso" è la parola chiave: una volta creato un array, la sua lunghezza non cambia mai. E "stesso tipo": un int[] contiene solo valori int, uno String[] contiene solo stringhe. Questa rigidità è il prezzo da pagare per avere array veloci e compatti in memoria.
Dichiari un tipo array mettendo [] dopo il tipo degli elementi, poi assegni un letterale oppure ne allochi uno con new:
Le parentesi possono stare dopo il tipo (int[] scores) o dopo il nome (int scores[]). Entrambe le forme compilano, ma int[] scores è lo stile idiomatico di Java: metti le [] insieme al tipo, dove devono stare.
Creare un array con new
Quando non conosci ancora i valori ma conosci la dimensione, usa new. Questo alloca le posizioni e le riempie con il valore predefinito del tipo:
I valori predefiniti non sono dati casuali: Java inizializza a zero ogni elemento. I tipi numerici partono da 0 (o 0.0), boolean parte da false e i tipi riferimento come String partono da null. Quel null merita attenzione: uno String[] appena allocato è pieno di null, e chiamare un metodo su uno di essi lancia una NullPointerException.
Gli indici partono da zero
Leggi e scrivi gli elementi tramite indice, contando da 0. L'ultimo indice valido è sempre length - 1:
A differenza degli array di alcuni linguaggi di scripting, uscire dall'intervallo non ti restituisce silenziosamente null o undefined: lancia un'eccezione. Prova a leggere un indice che non esiste:
Quel programma si interrompe con:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 3
È uno degli errori più comuni tra i principianti. La causa è quasi sempre un errore di uno nella condizione di un ciclo: usare <= quando intendevi <.
length è un campo, non un metodo
Ogni array porta con sé la sua dimensione in un campo length. Attenzione: niente parentesi.
Ecco una trappola in cui cadono tutti almeno una volta: gli array usano .length (un campo), ma una String usa .length() (un metodo). Scrivere nums.length() su un array è un errore di compilazione, e lo è anche scrivere text.length su una stringa. Stessa parola, regole diverse: quella degli array non ha parentesi.
Scorrere un array
Hai visto il ciclo for-each nella pagina precedente, ed è il modo più pulito per leggere ogni elemento quando non ti serve l'indice:
Quando ti serve l'indice, per stampare il numero di posizione, modificare gli elementi sul posto o scorrere all'indietro, usa il classico ciclo for con indice e length come limite:
La condizione è i < names.length, non <=. Con <= il ciclo fa un passo di troppo e lancia l'eccezione di indice fuori intervallo vista sopra. Una regola veloce: for-each quando leggi soltanto i valori, for con indice quando ti serve la posizione o vuoi riscrivere nell'array.
Array multidimensionali
Un array 2D è in realtà un array di array: pensalo come una griglia di righe e colonne. Aggiungi una seconda coppia di parentesi:
grid[row][column] seleziona una singola cella. Poiché ogni riga è un array a sé, grid.length è il numero di righe e grid[0].length è il numero di colonne della prima riga. Le righe non devono nemmeno avere la stessa lunghezza (si parla di array frastagliato, o jagged array), anche se la maggior parte delle griglie è rettangolare.
La classe di utilità Arrays
Gli array in sé non hanno quasi nessun metodo: non puoi ordinarne o stamparne uno direttamente in modo utile. Java offre la classe di utilità java.util.Arrays, piena di metodi statici proprio per questo:
Alcune cose su cui contare. Arrays.toString(arr) è il modo giusto per stampare un array: stamparlo direttamente produce una stringa inutile come [I@1b6d3586. Arrays.sort ordina sul posto. Arrays.copyOf è il modo per "ridimensionare": restituisce un nuovo array della lunghezza richiesta, riempiendo con i valori predefiniti (le due posizioni in più qui sopra valgono 0). E Arrays.binarySearch funziona correttamente solo su un array già ordinato.
Array o ArrayList
Usa un array semplice quando la dimensione è nota in anticipo e non cambierà: un insieme fisso di giorni della settimana, una scacchiera, dei dati di pixel. Gli array sono veloci e leggeri, ma la lunghezza fissa è un limite reale: non puoi aggiungere un settimo elemento a un array di lunghezza 6 senza costruirne uno completamente nuovo.
Appena devi aggiungere e rimuovere elementi liberamente, un array diventa scomodo. È a questo che serve ArrayList: una lista ridimensionabile che cresce e che gestisce la copia al posto tuo.
Prossimo passo: ArrayList
Quando non sai quanti elementi avrai, o quel numero cambia mentre il programma è in esecuzione, un array a lunghezza fissa ti intralcia. ArrayList è la risposta di Java: una lista che cresce e si riduce su richiesta, con i metodi add e remove al posto dei giochi di prestigio con gli indici. È il prossimo argomento.
Domande frequenti
Come si dichiara e inizializza un array in Java?
Dichiara il tipo con le parentesi quadre e assegna un letterale: int[] nums = {1, 2, 3};. Per creare un array vuoto di dimensione fissa, usa new: int[] nums = new int[5];, che ti dà 5 posizioni, ognuna riempita con il valore predefinito (0 per int, null per gli oggetti).
Come si ottiene la lunghezza di un array in Java?
Usa il campo length (senza parentesi): nums.length. È un campo, non un metodo, quindi nums.length() è un errore di compilazione. Nota che String usa .length() con le parentesi, mentre gli array usano .length senza: una confusione classica.
Un array Java può cambiare dimensione dopo essere stato creato?
No. Un array Java ha una lunghezza fissa decisa alla creazione e non puoi ingrandirlo né ridurlo. Se ti serve una lista ridimensionabile, usa un ArrayList. Per "ridimensionare" un array dovresti crearne uno nuovo più grande e copiarci dentro gli elementi.
Cos'è ArrayIndexOutOfBoundsException in Java?
È l'errore a runtime che ottieni quando accedi a un indice che non esiste, cioè minore di 0 oppure >= array.length. A differenza di altri linguaggi, Java non restituisce un valore predefinito o null per un accesso fuori intervallo: lancia un'eccezione. Gli indici validi vanno sempre da 0 a length - 1.