Klasyczna pętla for z trzema częściami
Pętla for powtarza blok kontrolowaną liczbę razy. W Javie w nawiasach mieszczą się trzy elementy oddzielone średnikami:
Te trzy części wykonują się w stałym rytmie:
- Inicjalizacja (
int i = 0): wykonuje się raz, przed wszystkim innym. - Warunek (
i < 5): sprawdzany przed każdym przebiegiem; pętla kończy się, gdy jest fałszywy. - Aktualizacja (
i++): wykonuje się po każdym przebiegu, zanim warunek zostanie sprawdzony ponownie.
Program wypisuje więc od i = 0 do i = 4. Licznik i istnieje tylko w pętli: po zamykającym nawiasie klamrowym już go nie ma.
Liczenie w górę, w dół i co krok
Trzy części dają pełną kontrolę nad licznikiem:
i-- zmniejsza licznik, a i += 5 przeskakuje o pięć: oba to arytmetyczne operatory, które liczą wartość licznika. Warunek decyduje o zatrzymaniu zależnie od kierunku: używaj > przy odliczaniu w dół, a < lub <= przy liczeniu w górę.
Pętla po tablicy
Pętla z licznikiem naturalnie łączy się z tablicą: .length służy jako granica, a i jako indeks:
Zauważ, że colors.length to pole bez nawiasów: pod tym względem tablice są wyjątkowe. List używa zamiast tego list.size(). Warunek i < colors.length jest poprawny: indeksy biegną od 0 do length - 1, więc użycie < (a nie <=) chroni przed wyjściem poza zakres.
Rozszerzona pętla for-each
Gdy potrzebujesz tylko kolejnych elementów, a nigdy indeksu, rozszerzone for jest czytelniejsze i trudniej w nim o błąd: nie ma licznika, który mógłby się pomylić o jeden:
Czytaj for (String color : colors) jako „dla każdego koloru w colors”. Działa na tablicach i na wszystkim, po czym można iterować. Cena: nie masz indeksu i nie możesz dodawać ani usuwać elementów kolekcji w trakcie pętli (to rzuca wyjątek w czasie działania, ConcurrentModificationException). Gdy potrzebujesz jednego z nich, sięgnij po pętlę z licznikiem.
Pętle zagnieżdżone
Pętla w pętli przydaje się do siatek, tabel i łączenia w pary. Wewnętrzna pętla wykonuje się w całości przy każdym przebiegu zewnętrznej:
Ten kod wypisuje tabliczkę mnożenia 3x3. Przy głębszym zagnieżdżeniu nadawaj licznikom znaczące nazwy (row, col) zamiast i, j: łatwiej wtedy odróżnić, który jest który.
break i continue
break natychmiast opuszcza pętlę. continue pomija resztę bieżącego przebiegu i przechodzi do kroku aktualizacji:
Program wypisuje 1 3 5 7. continue pomija liczby parzyste, a break kończy pętlę, gdy i przekroczyłoby 7. W pętlach zagnieżdżonych oba działają tylko na najbardziej wewnętrzną pętlę, chyba że użyjesz break z etykietą.
Uważaj na pętle nieskończone
Jeśli warunek nigdy nie stanie się fałszywy, pętla działa w nieskończoność. Zwykle przyczyną jest zapomniana aktualizacja albo zmiana licznika w złą stronę:
for (int i = 0; i < 5; i--) { // i tylko maleje -> nigdy nie osiągnie 5
System.out.println(i);
}
Celowa pętla nieskończona pomija wszystkie trzy części, for (;;) { ... }, i polega na break w środku, aby się zatrzymać. Używaj jej oszczędnie; while (true) zwykle czyta się łatwiej.
Dalej: pętle while
Pętla for sprawdza się, gdy znasz licznik z góry. Gdy chcesz powtarzać kod, dopóki nie zmieni się jakiś warunek, a nie masz wygodnego licznika, lepiej pasuje pętla while. To temat następnej strony.
Najczęściej zadawane pytania
Jaka jest składnia pętli for w Javie?
Pętla for w Javie ma w nawiasach trzy części oddzielone średnikami: for (initialization; condition; update) { ... }. Na przykład for (int i = 0; i < 5; i++) { ... } ustawia i na 0, wykonuje ciało, dopóki i < 5, i po każdym przebiegu dodaje 1 do i. Wszystkie trzy części są opcjonalne.
Czym różni się pętla for od pętli for-each w Javie?
Klasyczna pętla for używa jawnego licznika, więc kontrolujesz indeks i kierunek: najlepiej sprawdza się, gdy potrzebujesz indeksu albo chcesz pomijać elementy. Rozszerzona pętla for-each, for (Type item : collection), przechodzi po każdym elemencie po kolei bez indeksu: jest czytelniejsza, gdy potrzebujesz samych elementów, a nigdy pozycji. For-each nie może zmieniać struktury kolekcji w trakcie pętli.
Jak przejść pętlą po tablicy w Javie?
Albo indeksuj ją w pętli z licznikiem, for (int i = 0; i < arr.length; i++) { use arr[i]; }, albo, gdy nie potrzebujesz indeksu, użyj for-each: for (int x : arr) { use x; }. Tablice udostępniają rozmiar przez pole .length (bez nawiasów), a listy przez .size().