Menu

Tablice w Javie: deklaracja, inicjalizacja, dostęp i pętle

Jak działają tablice w Javie: stała długość, deklaracja i inicjalizacja, indeksowanie, length, pętle, tablice wielowymiarowe i klasa pomocnicza Arrays.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Tablica to lista o stałym rozmiarze

Tablica w Javie przechowuje stałą liczbę wartości tego samego typu, ułożonych po kolei i dostępnych według pozycji. Kluczowe jest słowo „stała”: po utworzeniu tablicy jej długość nigdy się nie zmienia. Równie ważne jest „tego samego typu”: int[] przechowuje tylko wartości int, a String[] tylko napisy. Ta sztywność to cena za to, że tablice są szybkie i oszczędne w pamięci.

Typ tablicowy deklarujesz, dodając [] po typie elementu, a potem przypisujesz literał albo tworzysz tablicę przez new:

Nawiasy mogą stać po typie (int[] scores) albo po nazwie (int scores[]). Oba zapisy się kompilują, ale int[] scores to idiomatyczny styl Javy: [] należy do typu, więc tam je umieszczaj.

Tworzenie tablicy przez new

Gdy nie znasz jeszcze wartości, ale znasz rozmiar, użyj new. Tworzy ono miejsca i wypełnia je wartością domyślną danego typu:

Wartości domyślne nie są przypadkowymi śmieciami: Java zeruje każdy element. Typy liczbowe zaczynają od 0 (lub 0.0), boolean od false, a typy referencyjne, takie jak String, od null. O tym null warto pamiętać: świeżo utworzona String[] jest pełna wartości null, a wywołanie metody na którejś z nich rzuca NullPointerException.

Indeksy zaczynają się od zera

Elementy odczytujesz i zapisujesz według indeksu, licząc od 0. Ostatni poprawny indeks to zawsze length - 1:

W przeciwieństwie do tablic w niektórych językach skryptowych wyjście poza zakres nie zwraca po cichu null ani undefined, tylko rzuca wyjątek. Spróbuj odczytać indeks, który nie istnieje:

Ten program kończy się błędem:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 3

To jeden z najczęstszych błędów początkujących. Przyczyną jest prawie zawsze pomyłka o jeden w warunku pętli: użycie <= tam, gdzie powinno być <.

length to pole, a nie metoda

Każda tablica przechowuje swój rozmiar w polu length. Uwaga: bez nawiasów.

Oto pułapka, na którą każdy trafia przynajmniej raz: tablice używają .length (pola), a String używa .length() (metody). Napisanie nums.length() dla tablicy to błąd kompilacji, tak samo jak text.length dla napisu. To samo słowo, inne zasady: wersja dla tablic nie ma nawiasów.

Pętla po tablicy

Pętlę for-each poznałeś na poprzedniej stronie i to najczytelniejszy sposób na odczytanie każdego elementu, gdy nie potrzebujesz indeksu:

Gdy potrzebujesz indeksu, żeby wypisać numery pozycji, zmienić elementy w miejscu albo iterować od końca, sięgnij po klasyczną pętlę for z indeksem i length jako granicą:

Warunek to i < names.length, a nie <=. Użycie <= wykonuje o jeden krok za dużo i rzuca wyjątek wyjścia poza zakres z poprzedniej sekcji. Prosta zasada: for-each, gdy tylko odczytujesz wartości, a for z indeksem, gdy potrzebujesz pozycji albo chcesz zapisywać do tablicy.

Tablice wielowymiarowe

Tablica 2D to tak naprawdę tablica tablic: wyobraź ją sobie jako siatkę wierszy i kolumn. Dodajesz drugą parę nawiasów:

grid[row][column] wybiera jedną komórkę. Każdy wiersz jest osobną tablicą, więc grid.length to liczba wierszy, a grid[0].length to liczba kolumn w pierwszym wierszu. Wiersze nie muszą nawet mieć tej samej długości (to tak zwana tablica postrzępiona, ang. jagged array), choć większość siatek jest prostokątna.

Klasa pomocnicza Arrays

Same tablice nie mają prawie żadnych metod: nie da się ich sensownie posortować ani wypisać bezpośrednio. Java udostępnia klasę narzędziową java.util.Arrays z mnóstwem statycznych metod pomocniczych właśnie do tego:

Kilka rzeczy, na których warto polegać. Arrays.toString(arr) to właściwy sposób na wypisanie tablicy: wypisanie jej bezpośrednio daje bezużyteczny napis w stylu [I@1b6d3586. Arrays.sort sortuje w miejscu. Arrays.copyOf to sposób na „zmianę rozmiaru”: zwraca nową tablicę o żądanej długości, uzupełnioną wartościami domyślnymi (dwa dodatkowe miejsca powyżej mają 0). A Arrays.binarySearch działa poprawnie tylko na już posortowanej tablicy.

Tablice a ArrayList

Używaj zwykłej tablicy, gdy rozmiar jest znany z góry i się nie zmieni: stały zestaw dni tygodnia, plansza do gry, dane pikseli. Tablice są szybkie i lekkie, ale stała długość to realne ograniczenie: nie dodasz siódmego elementu do tablicy o długości 6 bez budowania zupełnie nowej.

Gdy tylko musisz swobodnie dodawać i usuwać elementy, tablica staje się niewygodna. Do tego służy ArrayList: rozszerzalna lista o zmiennym rozmiarze, która sama zajmuje się kopiowaniem.

Dalej: ArrayList

Gdy nie wiesz, ile elementów będziesz mieć, albo ta liczba zmienia się w trakcie działania programu, tablica o stałej długości zaczyna przeszkadzać. Odpowiedzią Javy jest ArrayList: lista, która rośnie i kurczy się na żądanie, z metodami add i remove zamiast żonglowania indeksami. To temat następnej strony.

Najczęściej zadawane pytania

Jak zadeklarować i zainicjalizować tablicę w Javie?

Zadeklaruj typ z nawiasami kwadratowymi i przypisz literał: int[] nums = {1, 2, 3};. Aby utworzyć pustą tablicę o stałym rozmiarze, użyj new: int[] nums = new int[5];. Dostajesz wtedy 5 miejsc, z których każde ma wartość domyślną (0 dla int, null dla obiektów).

Jak sprawdzić długość tablicy w Javie?

Użyj pola length (bez nawiasów): nums.length. To pole, a nie metoda, więc nums.length() to błąd kompilacji. Zauważ, że String używa .length() z nawiasami, a tablice .length bez nich. To klasyczna pomyłka.

Czy tablica w Javie może zmienić rozmiar po utworzeniu?

Nie. Tablica w Javie ma stałą długość ustaloną przy tworzeniu i nie da się jej powiększyć ani zmniejszyć. Jeśli potrzebujesz listy o zmiennym rozmiarze, użyj ArrayList. Aby „zmienić rozmiar” tablicy, trzeba utworzyć nową, większą i skopiować do niej elementy.

Czym jest ArrayIndexOutOfBoundsException w Javie?

To błąd w czasie działania programu, który pojawia się przy odwołaniu do nieistniejącego indeksu: mniejszego od 0 albo >= array.length. W przeciwieństwie do niektórych języków Java nie zwraca wartości domyślnej ani null przy wyjściu poza zakres, tylko rzuca wyjątek. Poprawne indeksy zawsze biegną od 0 do length - 1.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ