Darmowy kurs Java

Tablice wielowymiarowe

W tej lekcji kursu poznamy tablice wielowymiarowe, które są naturalnym rozszerzeniem tablic jednowymiarowych. Różnią się przede wszystkim sposobem deklaracji i odwoływania do jej elementów. Za jej pomocą można na przykład w łatwy sposób wyobrazić sobie grę w statki - można przechowywać za pomocą współrzędnych miejsce położenia statków. Tablice wielowymiarowe w języku Java to tak naprawdę tablice tablic. Jako ciekawostka w języku C# istnieją zarówno tablice jedno i wielowymiarowe, oraz tablice wielowymiarowe takie jak w Javie (tablice tablic).

Schematyczna deklaracja wygląda tak:

typ[][] nazwa_tablicy; //deklaracja
nazwa_tablicy = new typ[liczba1][liczba2]; //przypisanie (utworzenie)
typ[][] nazwa_tablicy2 = new typ[liczba1][liczba2]; //deklaracja i przypisanie (utworzenie)

Widzimy, że podobnie jak w przypadku tablic jednowymiarowych możemy zarówno zadeklarować i utworzyć tablicę w dwóch różnych miejscach jak i połączyć te operacje ze sobą. Powyżej utworzyliśmy tablicę dwuwymiarową. Struktura taka może przechowywać liczba1*liczba2 elementów. Nic nie stoi na przeszkodzie, aby utworzyć tablice 3 i więcej wymiarowe, ale zazwyczaj nie jest to potrzebne, a na pewno nie jest to praktyczne. Do elementów tablic wielowymiarowych odwołujemy się analogicznie, jak w przypadku jednowymiarowych, możemy sobie wyobrazić, że to podawanie współrzędnych punktów, przykładowo:

int[][] tablica = new int[3][3];
tablica[2][1] = 5;
int zmienna = tablica[2][1];

W ten sposób utworzyliśmy tablicę dwuwymiarową mogącą przechować 9 elementów. Do komórki pod współrzędną (2,1) zapisaliśmy wartość 5, a następnie wykorzystaliśmy ją do zainicjowania zmiennej.

Kurs Programowania Java

Ciekawą i często użyteczną funkcjonalnością jest to, że tablica wielowymiarowa nie musi być symetryczna. Przykładowo:

int[][] tablica = new int[3][];
tablica[0] = new int[3];
tablica[1] = new int[2];
tablica[2] = new int[1];

Jeśli byśmy zainicjowali wszystkie jej elementy na przykład w poniższy sposób:

	  for(int i=0; i< tablica.length; i++)
		  for(int j=0; j< tablica[i].length; j++)
			  tablica[i][j] = 0;

Użyliśmy tu ważnej własności każdej tablicy, mianowicie length (zauważ, że nie jest to metoda i nie jest zakończona nawiasami() ). Określa ona jej długość, tutaj należy zapamiętać, że zwracana wielkość jest rzeczywista, a nie liczona od 0. W naszym powyższym przykładzie jej wywołania przedstawiają się tak:

    • tablica.length = 3 (bo mamy new tablica[3][x];

    • tablica[0].length = 3

    • tablica[1].length = 2

    • tablica[2].length = 1

    Dzięki temu po wydruku danych w podobny sposób:

    	  for(int i=0; i< tablica.length; i++){
    		  for(int j=0; j< tablica[i].length; j++)
    			  System.out.print(tablica[i][j]);
    		  System.out.println();
    	  }

    Uzyskamy wynik postaci

    000

    00

    0

    Własność length posiada każda tablica w Javie, także jednowymiarowa. Przy wypełnianiu, lub wyświetlaniu danych przy użyciu pętli jej używanie jest zdecydowanie wskazana, ponieważ zwiększa to uniwersalność kodu. Przy zmianie wielkości tablicy przy jej tworzeniu nie musimy poprawiać dalszej części kodu, ponieważ jest on elastyczny.

    Zadania do samodzielnego wykonania:

    1.14 Przy użyciu pętli i tablic przechowujących liczby całkowite zaprezentuj poniższą treść:

    tab[0,0] = 0;

    tab[0,1] = 1;

    tab[0,2] = 2;

    tab[1,0] = 3;

    tab[1,1] = 4;

    tab[1,2] = 5;

    Wykorzystuj przy tym własność length.

    Rozwiązanie.

    Zapisz się do newslettera

    Otrzymuj nasz Newsletter z przykładowymi pytaniami rekrutacyjnymi, wyzwaniami programistycznymi i nowościami ze świata Javy, a także informacje o nowych kursach i promocjach.

    Traktujemy Twoją prywatność poważnie. Nikomu nie udostępniamy Twojego maila no i zawsze możesz się wypisać.

    Komentarze do artykułu

    Wyłączyliśmy możliwość dodawania komentarzy. Poniżej znajdziesz archiwalne wpisy z czasów gdy strona była jeszcze hobbystycznym blogiem. Zapraszamy natomiast do zadawnia pytań i dyskusji na naszej grupe na facebooku.

    Mateusz

    Masz literówkę: "Jako ciekawostka w języku C# istnieją zarówno tablice jedno i wielowymiarowe, oraz tablice wielowymiarowe JAKIE jak w Javie.", powinno chyba być "TAKIE jak w Javie". Świetny kurs, dzięki za napisanie, dokładnie czegoś takiego szukałem!

    Mateusz

    "int[][] tab = new int[3][]; tablica[0] = new int[3]; tablica[1] = new int[2]; tablica[2] = new int[1];" nie powinno być w pierwszej linijce: int[][] tablica = new int[3][];

    Slawek

    owszem powinno, dzięki.

    Wojtek

    nazwa_tablicy = new typ[ilosc1][ilosc2]; //przypisanie (utworzenie) Błąd językowy - ilość odnosi się do rzeczy niepoliczalnych (ilość wody, ilość mąki), tutaj mówimy o "liczbie" ("liczba wierszy", nie "ilość wierszy")

    Slawek

    Dzięki, humanista ze mnie marny ;)

    Krzysiek

    Witam ponownie, gdyż znowu mam zaćmienie a chce już ten dział podstaw zakończyć. Czy można tabele wielowymiarową wyświetlić za pomocą pętli for each a jeśli tak to jak? Kiedy wrzucam zapis for(int x: a) to nie kompiluje tego bo czepia się, że "a" to "int[]" a wymagany jest "int". Kiedy użyję zapisu for(int[]x: a) to kompiluje ale na tym kończy się radocha bo po uruchomieniu wyświetlają się jakieś cuda niewidy typu [[I@15e8f2a0[[I@15e8f2a0[[I@15e8f2a0 czyli 3 x [[I@15e8f2a0 :(. A co z wyświetleniem za pomocą pętli while przy wielowymiarówkach, czy jest możliwe? Wystarczą mi konkretne przykłady, nie trzeba tłumaczyć.

    Slawek

    int[][] x = new int[5][5];
    		for(int i=0; i<5; i++)
    			for(int j=0; j<5; j++)
    				x[i][j] = i*5+j;
    		
    		for(int[] wiersz: x)
    			for(int element: wiersz)
    				System.out.println(element);
    
    int wiersz = 0;
    		int kolumna = 0;
    		while(wiersz < x.length) {
    			kolumna = 0;
    			while(kolumna < x[wiersz].length) {
    				System.out.println(x[wiersz][kolumna]);
    				kolumna++;
    			}
    			wiersz++;
    		}
    

    Krzysiek

    Dzięki, to wszystko jest proste jak już się wie:) Pętle jak pętle, ale ten zapis mnie rozbroił x[i][j] = i*5+j; To tylko takie proste działanie matematyczne (0*5+0, 0*5+1, 0*5+2, 0*5+3, 0*5+4, 1*5+0, 1*5+1 ...... 4*5+3, 4*5+4) a wieki by mineły zanim sam bym doszedł jak wypełnić tablicę liczbami jedną po drugiej, jeśli w ogóle bym do tego doszedł. Tu nie matma a wyobraźnia i pomysłowość najważniejsza. Do tej pory mi wyświetlało 111222333 i myślałem, że jak poradzę sobie z pętlami to i to się jakoś wyjaśni. Wyprzedziłeś fakty. Dobra teraz powtórka już samych zadań z tego działu i spadam dalej:)

    Krzysiek

    He He :))) Wypełnienie liczbami w odwrotnej kolejności :):):) int[][] x = new int[5][5]; int d = 5; for(int i=0; i<5; i++){ int e = 0; for(int j=0; j<5; j++){ x[i][j] = d*5-e; e++;} d--;} for(int[] wiersz: x) for(int element: wiersz) System.out.println(element); } }

    Krzysiek

    Ale w sumie można łatwiej więc po co te kombinacje z mnożeniem i dwoma zmiennymi? Po kolei: int[][] tab = new int[5][5]; int a = 0; for(int i = 0; i < tab.length; i++) for(int j = 0; j < tab[i].length; j++){ tab[i][j] = a++;} i w drugą strone: int[][] tab = new int[5][5]; int a = 25; for(int i = 0; i < tab.length; i++) for(int j = 0; j < tab[i].length; j++){ tab[i][j] = a--;}

    HELP

    Moze ktoś wytłumaczyć ten "rozbrajający" zapis x[i][j] = i*5+j

    lolo

    Zapis x[i][j] = i*5+j oznacza tyle, że do tablicy dwuwymiarowej x[][] do komórki o indeksie x[i][j] ( np. zmienna i=5 i j=6 to do komórki o indeksie [5][6]) zostanie wpisany wynik z działania i*5+j (w podanym przezemnie przepadku będzie to wynik z 5*5+6 czyli 31).

    HELP

    Dzięki nawet nie myślałem, że ktoś odpisze.

    Marek

    int[][] tablica = new int[3][]; tablica[0] = new int[3]; tablica[1] = new int[2]; tablica[2] = new int[1]; o co chodzi w tym zapisie?

    Krzysiek

    int[][] tablica = new int[3][]; /* podajesz ilość wierszy, natomiat ilość kolumn pozostawiasz pustą i rozpisujesz każdą koumnę z osobna, gdyż do każdego wiersza chcesz dopisać inną ilość kolumn. Gdybyś napisał odrazu np. int[][] tablica = new int[3][4]; to każdy z 3 wierszy miał by po 4 kolumny, a tak to:/ tablica[0] = new int[3]; // wierszowi pierwszemu przypisujesz 3 kolumny tablica[1] = new int[2]; // wierszowi drugiemu 2 kolumny tablica[2] = new int[1]; // wierszowi trzeciemu 1 kolumnę Sprawdź sobie też to http://www.java2s.com/Book/Java/0020__Language-Basics/Multidimensional_Arrays.htm

    Marek

    A czy można pozostawić pustą ilość wierszy a ilość kolumn podać np. 3 ? Czyli : int[][] tablica = new int[][3]; ?

    Krzysiek

    Przeciez kolumna nie moze istniec bez wiersza, bo w czym ja "zawiesisz"? w nicosci? int[][] tablica = new int[][3]; to juz na dzien dobry znaczy int[][] tablica = new int[1][3]; czyli 3 kolumny w jednym wierszu.

    Witek

    Witam Codzi Ci o tzw. tablice nieregularne, wymagany jest tylko pierwszy rozmiar, natomiast drugi może być pusty np.: „ int tab[][] = new int[3][] ; “ , a pozostałe rozmiary możesz zaalokować odzielnie.

    Fiesta

    while(licznik<tablica.length){ System.out.print(tablica[i]+" ") licznik++; }tutaj chyba błąd jest, klasa nie jusmpilkoe się bo zmienna [i] jest deklarowana w for-ach i tylko tam istnieje

    aaantek

    Witam można wydrukować dane z tablicy wielowymiarowej za pomocą pętli for each? jeśli tak to jak to zapisać?

    Bogdan

    Ciekawą i często użyteczną funkcjonalnością jest to, że tablica wielowymiarowa nie musi być symetryczna. Słowo "symetryczna" jest w tym miejscu całkowicie nieodpowiednie. Proponuję Ciekawą i często użyteczną funkcjonalnością jest to, że tablica dwuwymiarowa nie musi być prostokątna (analogicznie dla wyższych wymiarów).

    pavon147

    Napotkałem na ciekawy problem. Nie będę wrzucał tutaj kodu, chyba, że będzie to konieczne, ale postaram się opisać po prostu tą sytuację. Tworzę tablicę wielowymiarową typu String. Użytkownik podaje jej wymiary oraz wypełnia ją. I teraz co się dzieje. Po pobraniu rozmiarów tablicy następuje jej wypełnienie za pomocą pętli for, oczywiście user podaje wszystko po kolei i wszystko byłoby ok tylko, że pętla przechodzi przez pierwsze przejście nie czekając na dane od użytkownika. Zachowuje się tak, jakby użytkownik nacisnął ENTER (podczas kolejnych przejść wszystko działa jak należy). Do pobierania danych wykorzystuję funkcję nextLine(); Udało mi się to jednak rozwiązać, wszedłem na stronę Oracle i znalazłem funkcję next(); i po jej zastosowaniu wyżej opisany błąd nie występuje. Chciałem prosić o wytłumaczenie różnicy między nextLine(); a next(); bo po prostu to co jest napisane w krótkim wyjaśnieniu pod tymi funkcjami na stronie Oracle nie pasuje mi do tego, co dzieje się w kodzie, więc chyba czegoś nie rozumiem. Z góry dzięki za odpowiedź ;)

    adamglos92

    Po pierwsze gratuluję wspaniałego kursu:) Po drugie jako ciekawostkę zamieszczam rozwiązanie bez użycia podwójnej pętli: public class TabWiel{ public static void main (String[] args){ int[][] tablica = new int[2][3]; for (int i=0 ; i<tablica.length*tablica[0].length ; ++i) tablica[i/3][i%3]=i+1; for (int i=0 ; i<tablica.length*tablica[0].length ; ++i) System.out.print(tablica[i/3][i%3]+" "); } }

    Marcin

    Witam. Może mi ktoś wskazać błąd w tym kodzie ? Meczy się z tym od jakiegoś czasu.... Chodzi o zapełnienie tablicy danymi z użyciem pętli "while". Oto listing: class Main{ public static void main(String args[]){ int[][]tab=new int[4][]; tab[0]=new int[4]; tab[1]=new int[3]; tab[2]=new int[2]; tab[3]=new int[1]; int licznik=1; int i=0; int j=0; while(i<tab.length){ while(j<tab[i].length){ tab[i][j]=licznik++; j++; } i++; } for(i=0;i<tab.length;i++){ System.out.print("tab["+i+"]="); for(j=0;j<tab[i].length;j++){ System.out.print(tab[i][j]+" "); } System.out.println(""); } } }

    Marcin

    oooo widzisz :) Dzięki wielkie!

    Marcin

    P.S. Bład polega na tym ze tylko pierwszy wiersz jest zapełniony liczbami a kolejne juz zamiast dalszymi to same zera....

    Marcin Kunert

    Zapominasz zerować zmiennej "j" w wewnętrznej pętli. public static void main(String args[]) { int[][] tab = new int[4][]; tab[0] = new int[4]; tab[1] = new int[3]; tab[2] = new int[2]; tab[3] = new int[1]; int licznik = 1; int i = 0; int j = 0; while (i < tab.length) { j = 0; while (j < tab[i].length) { tab[i][j] = licznik++; j++; } i++; } for (i = 0; i < tab.length; i++) { System.out.print("tab[" + i + "]="); for (j = 0; j < tab[i].length; j++) { System.out.print(tab[i][j] + " "); } System.out.println(""); } }

    dqbEd1

    Cześć. Tworzę prostą grę - statki, i mam problemy z właśnie tablicą wielowymiarową. Otóż przy próbie przypisania wartości konkretnemu polu tab[2][3] = 1; zeruje mi się cała tablica, a potem ustawiana jest wartość 1 dla pola 2; 3. Ktoś może mi coś doradzić? :)

    dqbEd1

    Dla pewności nawet wyświetlam sobie zawartość tablicy przed i po próbie nadania wartości, i działa tak jak opisałem powyżej.

    adrian

    Mógłby ktoś wytłumaczyć mi krok po kroku co się dzieje w jakimś przykładowym kodzie z tablicami dwuwymiarowymi? Z jednowymiarowymi dałem radę, ale teraz znowu klops. Jakiś przykładowy kod z tablicą dwuwymiarową, i np. pętlą for. Krok po kroku, co się dziej w programie, od początku do końca.

    Maciek

    Też właśnie stanąłem jakoś na tej lekcji, wcześniejsze przeszedłem bezboleśnie tylko tutaj jakoś nie rozumiem po prostu jak rzeczy działają(polecenia zadania tez w sumie;/) :( Podczepiam się o prośbę o jakieś przykłady dodatkowe) A ogólnie kurs super ! :D Najlepsze do czego dotarłem(a z programowaniem do czynienia wczesniej nie miałem wgl) Pozdrawiam

    Piotr

    Witam, Posiadam takiego maina i mam problem gdyż wynik sie nie zgadza z zamieszczonym. public class Pro{ public static void main(String[] args){ int[][] tab = new int[3][3]; for(int i=0;i<tab.length;i++){ for(int j=0;j<tab[i].length;j++){ System.out.print(tab[i][j]); } System.out.println(); } } } dostaje: 000 000 000

    lolo

    Przecież zadeklarowałeś tablicę 3x3 standardowo jest uzupełniana 0 bo nie wpisałeś innych wartości. To co Ci się nie zgadza?

    Piotr

    powinno być podobno tak: 000 00 0

    lolo

    Napisałeś: int[][] tab = new int[3][3]; A nie jak w przykładzie u góry: int[][] tablica = new int[3][]; tablica[0] = new int[3]; tablica[1] = new int[2]; tablica[2] = new int[1]; Przyjmijmy, że tablica wielowymiarowa jest to tabliczka czekolady a każdy jeden element [ ] to kostka tejże czekolady. Ty deklarujesz tabliczkę czekolady 3 na 3. Czyli mamy 3 wiersze i w każdym po 3 kolumny: [ ][ ][ ] [ ][ ][ ] [ ][ ][ ] A w przykładzie zdeklarowana jest tabliczka o 3 wierszach kostek (pierwsza linijka int[][] tablica = new int[3][];) [ ] [ ] [ ] I w kolejnych linach deklarowana jest ilość kostek znajdujących się w każdym wierszu naszej tabliczki czekolady W pierwszym wierszu tablica[0] = new int[3]; deklarowane są 3 kostki W drugim wierszu tablica[1] = new int[2]; deklarowane są 2 kostki i w trzecim wierszu tablica[2] = new int[1]; zdeklarowana jest 1 kostka [ ][ ][ ] [ ][ ] [ ]

    Janosch

    Świetne porównanie, właśnie czegoś takiego mi było trzeba!

    D

    public class wielowymiarowe { public static void main(String[] args) { // TODO Auto-generated method stub int[][] tablica = new int[3][]; tablica[0] = new int[3]; tablica[1] = new int[2]; tablica[2] = new int[1]; for(int i=0; i<tablica.length; i++){ for(int j=0; j<tablica[i].length; j++){ System.out.println(tablica[i][j]); } System.out.println(); } } } A wynik w konsoli jest taki: 0 0 0 0 0 0 Dlaczego?

    G.Jeszka

    Bo jest błąd w pętli, w złym miejscu jest wprowadzana new line. for(int i=0; i<tab.length; i++){ for(int j=0; j<tab[i].length; j++){ System.out.print(tab[i][j]); } System.out.println(); }

    thingness

    O własności length powinien Pan napisać w poprzedniej lekcji o tablicach jednowymiarowych. :D Pozdrawiam

    snt.banzai

    Przyznam się szczerze, ze gdyby nie komentarze to nic bym z tej lekcji nie zrozumiał.

    Damian

    mysle ze dla niektorych osob bedzie to niezrozumiale poniewaz nie widza oni 2 kolumna po 3 wiersze, w tym przypadku jedna tablica jest pod druga ,moze zapis tab[0,0] = 0; tab[1,0] = 3; tab[0,1] = 1; tab[1,1] = 4; tab[0,2] = 2; tab[1,2] = 5; cos podpowie;)

    Mikołaj

    Mam pytanie. Otóż w zadaniu jest aby zrobić pętle wypełniającą tablice w sposób "poziomy", czyli po kolei 012345 od lewej do prawej: tab[0,0] = 0; tab[0,1] = 1; tab[0,2] = 2; tab[1,0] = 3; tab[1,1] = 4; tab[1,2] = 5; Jak w takim razie napisać to, aby wypełniało tablicę w sposób "pionowy, czyli z góry na dół? (Wyglądało by to tak): tab[0,0] = 0; tab[0,1] = 2; tab[0,2] = 4; tab[1,0] = 1; tab[1,1] = 3; tab[1,2] = 5; Proszę o odpowiedź :)

    Szkolenie Java Wrocław