Java for Loop
Itera un numero fisso di volte in Java con il ciclo for — inizializzazione, condizione ed espressioni di aggiornamento.
Il ciclo for è il principale strumento di iterazione in Java. Raggruppa tre elementi — cosa fare prima del ciclo, cosa verificare prima di ogni iterazione e cosa fare dopo ogni iterazione — in un'unica intestazione. Il risultato è più compatto e meno soggetto a errori rispetto alla stessa cosa scritta con while.
Sintassi
for (initialization; condition; update) {
// body
}Tre parti separate da punto e virgola:
- Inizializzazione — viene eseguita una sola volta, prima dell'avvio del ciclo. Di solito dichiara il contatore.
- Condizione — verificata prima di ogni iterazione. Se è falsa, il ciclo termina.
- Aggiornamento — viene eseguito dopo ogni iterazione. Di solito incrementa il contatore.
for (int i = 0; i < 5; i++) {
System.out.println(i);
}Stampa 0 1 2 3 4. L'intestazione si legge così: inizia con i = 0, esegui finché i < 5, incrementa i ogni volta.
Forma equivalente con while
Un ciclo for è meccanicamente equivalente a questo while:
{
int i = 0; // initialization
while (i < 5) { // condition
System.out.println(i);
i++; // update
}
}Il vantaggio del for è che tutto ciò che controlla il ciclo si trova su una sola riga, rendendo l'intenzione ovvia a colpo d'occhio.
Varianti di conteggio
L'intestazione del for è flessibile. Le tre parti possono essere qualsiasi cosa:
// counting down
for (int i = 10; i > 0; i--) { ... }
// stepping by 2
for (int i = 0; i < 100; i += 2) { ... }
// looping over an array by index
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}Se non hai bisogno di una parte particolare, puoi ometterla — ma mantieni i punti e virgola:
for (;;) { // identical to while (true)
if (done()) break;
}Il problema dell'errore off-by-one
Il bug più comune nei cicli for è scegliere l'operatore di confronto sbagliato. Quando si indicizza un array di lunghezza n, gli indici validi vanno da 0 a n - 1, quindi la condizione deve essere i < n (non i <= n):
int[] arr = {10, 20, 30}; // length 3, indices 0..2
for (int i = 0; i <= arr.length; i++) {
System.out.println(arr[i]); // throws ArrayIndexOutOfBoundsException when i == 3
}Sostituire <= con < risolve il problema. Una regola semplice: usa < con un contatore o con length, e riserva <= a un valore finale esplicito (ad es. for (int i = 1; i <= 5; i++)).
Scope della variabile del ciclo
Una variabile dichiarata nella clausola di inizializzazione è locale al ciclo. Al termine del ciclo, non è più accessibile:
for (int i = 0; i < 5; i++) {
// i is visible here
}
// i is not visible hereQuesto è intenzionale — impedisce di fare affidamento accidentalmente sul valore finale del contatore. Se hai bisogno del valore al di fuori del ciclo, dichiaralo prima:
int i;
for (i = 0; i < 5; i++) {
if (someCondition(i)) break;
}
System.out.println("stopped at i=" + i);Più variabili in un'unica intestazione
Puoi dichiarare e aggiornare più di una variabile, separate da virgole:
for (int i = 0, j = 10; i < j; i++, j--) {
System.out.println(i + " " + j);
}A volte è utile — ma se un ciclo necessita di più di due variabili che interagiscono tra loro, di solito è un segnale per fare refactoring in parti più piccole.
Quando scegliere for rispetto a while
Usa un ciclo for quando sai — o puoi esprimere in una riga — quante iterazioni hai bisogno o quale intervallo stai scansionando. Usa un ciclo while quando la condizione di arresto è indipendente da un contatore (ad es. "finché l'input non è esaurito", "finché non si ha successo").
Per scorrere un array o una collection elemento per elemento, il ciclo for-each è quasi sempre più leggibile.
Un esempio pratico
Cosa c'è dopo
Quando vuoi semplicemente visitare ogni elemento di un array o di una collection senza gestire un indice, il ciclo for-each è lo strumento giusto.