Kurs java dla początkujących - #3 tablice

Kurs Java dla początkujących – #3 Tablice

W poprzednich częściach kursu dowiedziałeś się już co nieco o programowaniu i o tym, jak zacząć swoją przygodę z programowaniem. Teraz czas przejść do kolejnych elementów języka Java, które pomogą Ci w codziennych zmaganiach z programowaniem. W tej części, będziemy mówili o tablicach i o tym do czego możemy je wykorzystać.

Co to są tablice ?

Tablice to obiekty, które są podstawowymi kontenerami, w których możemy przechowywać wartości (dane). Skoro są obiektami, mają także swój typ. W Javie możemy utworzyć tablice dowolnego typu. Java wymusza, by wszystkie elementy zawarte w tablicy były tego samego typu (nie dotyczy to typu bazowego Object). Konstruowanie tablic jest bardzo proste i możemy to zrobić na różne sposoby np.

// sposób 1
int[] array = new int[] {1,2,3,4};

// sposób 2
int[] array = new int[4];
array[0] = 1;
array[1] = 2;
array[2] = 3;
array[3] = 4;

Sposób 1.

Typ zmiennej tablicowej zawsze zapisujemy w taki sam sposób. Najpierw typ (int) później nawiasy kwadratowe ([]), potem nazwa zmiennej (tutaj array). I w ten sposób otrzymujemy zmienną int[] array, do której przypisujemy obiekt tablicy (operator przypisania „=”), który tworzymy standardowo przez new. Dalej obiekt, który tworzymy int[]. A następnie w nawiasach klamrowych ({}), co oznacza inicjalizacja tablicy. Czyli poszczególnym elementom przypisujemy kolejne wartości cyfr od 1 do 4.

Sposób 2.

Drugi sposób różni się od pierwszego dwiema rzeczami:

  • w miejscu gdzie deklarujemy zmienną i tworzymy obiekt tablicy nie inicjalizując jej od razu, tak jak w poprzednim przykładzie (inicjalizacja elementów odbywa się w kolejnych liniach);
  • podajemy długość tablicy (new int[4]).

Podanie długości tablicy jest bardzo ważne, ponieważ tablice mają zawsze ustaloną długość. Nie możemy zmienić długości już istniejącej tablicy. Mimo że w pierwszym sposobie nie podawaliśmy jawnie jej długości, to kompilator mógł „od razu zorientować się” ile elementów jest w tej tablicy.

Jeśli do naszej tablicy spróbujemy dodać element na kolejnym indeksie array[4] = 5;, to Java zgłosi nam wyjątek java.lang.ArrayIndexOutOfBoundsException (co oznacza, że nie możemy przypisać do tablicy więcej elementów niż wynosi jej rozmiar).

Wyjątki w Javie – w języku Java błędy obsługiwane są przez system wyjątków. Wyjątki są specjalnymi obiektami, które są używane tylko do tego celu. Zwykle zawierają informację (message), która pomaga zidentyfikować przyczynę problemu (w tym wypadku będzie to numer nieistniejącego indeksu tablicy, czyli 4). Oraz tzw. stacktrace, czyli listę wszystkich metod przez które przechodzi danych wyjątek, wraz z numerami wierszy. Dzięki czemu można dokładnie zlokalizować w kodzie, gdzie dany wyjątek wystąpił.

Pomimo, że oba sposoby są równoważne, to w zależności od potrzeb będziemy je stosować w różnych kontekstach. Pierwszy sposób jest zwykle przeznaczony do deklarowania tablic stałych. Drugi zaś wszędzie tam gdzie nie mamy podanych elementów tablicy od razu (np. jeśli generujemy je losowo).

Tablice mają jeszcze jedną charakterystyczną cechę. Ich indeksy liczone są od zera („0”) a nie od jednego („1”).

Przykładowe typy tablic w języku Java:

String[] strings = new String[] {"a", "b", "c"};
float[] floats = new float[] {1.1f, 1.2f, 1.3f};
char[] chars = new char[] {'a', 'b', 'c'};

Praca z tablicami

Wiesz już, że tablice są kontenerami na dane. Czasem mogą przechowywać bardzo duże ilości elementów – nie ma tutaj jakiś specjalnych limitów, jedynym ograniczeniem może być pamięć naszego komputera. Teraz dowiesz się jak używać tablic.

Przypisanie

Za każdym razem, gdy będziesz chciał zmienić element tablicy, pomocna będzie instrukcja przypisania (operatorem przypisania jest pojedynczy znak równości „=”), poznaliśmy już tę instrukcję wcześniej:

array[0] = 10;

oznacza to, że elementowi o indeksie 0 przypiszemy wartość 10. Możesz dowolnie zmieniać wartości tablic.

Pobranie pojedynczej wartości

Gdy będziesz chciał pobrać i np. wyświetlić któryś z elementów tablicy. Zrobisz to w taki sposób:

System.out.println(array[0]);

Możesz w ten sposób pobrać dowolny element.

Wyświetlanie i modyfikowanie wszystkich elementów (iteracja)

Aby wyświetlić wszystkie elementy w sposób ciągły (jeden po drugim) musimy dokonać tzw. iteracji. Używamy do tego mechanizmu pętli (o pętlach będzie jeszcze w kolejnych częściach). W tym wypadku użyjemy pętli for, wygląda ona tak:

Pętla for – to jedna z najbardziej powszechnych pętli w Javie (ale także w innych językach programowania), która pozwala nam iterować, zbiory danych takie jak tablice i kolekcje. Jej konstrukcja składa się z charakterystycznych elementów: słowa kluczowego for, oraz trzech parametrów oddzielonych średnikiem:

  • pierwszy to inicjalizacja licznika w tym wypadku o int i=0,
  • drugi to warunek, który ogranicza liczbę obrotów pętli, tutaj: i < array.length (i mniejsze od długości tablicy), co oznacza, że będziemy mieli tyle obrotów pętli ile elementów jest w naszej tablicy,
  • wyrażenie, które zwiększa licznik i++ (inkrementacja) jest to skrót od wyrażenia i = i + 1 co oznacza, że z każdym obrotem pętli zwiększamy licznik o jeden.
for(int i=0; i < array.length; i++) {
  System.out.println(array[i]);
}

W ten sposób wyświetlamy wszystkie elementy listy jeden pod drugim.

Korzystając z pętli for możemy też zmieniać elementy tablicy jeden po drugim lub po prostu ustawiać ich wartości jeśli są puste:

int[] array = new int[4]; // 1 
for(int i=0; i < array.length; i++) {
  array[i] = i; // 2 
}
System.out.println(Arrays.toString(array)); // 3
  1. deklarujemy pustą tablicę,
  2. wypełniamy wszystkie elementy poszczególnymi indeksami,
  3. używamy specjalnej metody Arrays.toString(...) do wydrukowania zawartości tablicy.

Przydatne funkcje tablic

Tablice są obiektem, ale nie mają za wiele metod, które możemy na nich wywołać. A właściwie jest tylko jedna metoda .clone(), która pozwala sklonować tablicę (wykonać jej kopię), ale nie powinieneś jej używać, zanim nie zgłębisz tematu klonowania obiektów (co jest tematem bardziej zaawansowanym).

Tablice mają jeszcze specjalny atrybut array.length, zwracający ilość elementów, które tablica może przechowywać – w skrócie długość tablicy.

Jest jeszcze kilka przydatnych funkcji z klasy Arrays, są to metody:

Array.toString(int[] array) – pozwala wydrukować zawartość tablicy. Normalnie gdy próbujemy coś wydrukować na konsoli, używamy do tego System.out.println(array), ale w przypadku tablicy ta instrukcja drukuje: [I@1b6d3586, co jest niejawnym wywołaniem metody .toString() na obiekcie tablicy. Każdy obiekt w Javie może mieć swoją implementację metody .toString(), ale jeśli nie jest ona zaimplementowana, Java używa implementacji domyślnej. Nie można nadpisać metody .toString() dla tablic, więc używana jest implementacja domyślna, która drukuje taki  lub podobny ciąg znaków (w tej chwili nie jest istotne dlaczego ten ciąg znaków wygląda właśnie tak).

Arrays.deepToString(Object[] array) – metoda ta jako parametr przyjmuje tablicę obiektów. Dzięki czemu można wydrukować wszystkie obiekty wraz z ich zwartością.

Arrays.copyOf(int[] original, int newLength) – kopiuje tablicę do nowej tablicy przy czym nowa tablica może mieć taki sam rozmiar jak poprzednie, ale nie musi. Może być większa lub mniejsza od poprzedniej.

Arrays.sort(int[] array) – sortuje ona tablicę podaną jako parametr.

Klasa Array zawiera także powyższe metody w różnych wersjach dla wszystkich typów podstawowych zawartych w Javie. Ma wiele wariantów różnych metod z kombinacjami różnych parametrów. Zachęcam do zajrzenia do dokumentacji.

Wady i zalety tablic

Jedną z podstawowych wad tablic jest to, że mają ustalony rozmiar. Często jest to niewygodne w codziennym programowaniu. Zwłaszcza jeżeli odczytujemy dane z plików, nie znając ich długości, czy pobieramy dane z bazy danych nie wiedząc ile wierszy zostanie zwróconych. Oczywiście nie jest to problem, którego nie da się rozwiązać, ale bywa to bardzo żmudne (problem ten rozwiązują kolekcje, o których przeczytasz w następnej części).

Kolejną wadą jest brak odpowiednich metod: do wyszukiwania, takich jak contains(...), czy do usuwania remove(...), czy do czyszczenia całej tablicy clear(). Oczywiście wszystkie te operacje możemy zrealizować za pomocą pętli, posługując się bezpośrednim dostępem do elementów tablicy poprzez indeks, ale zwykle wymaga to od nas pisania więcej kodu. Oczywiście i ten problem został rozwiązany w kolekcjach.

Jeśli chodzi o zalety to, powyższe dwa punkty w pewnych sytuacjach można rozpatrywać jako plusy. Gdy mamy do czynienia ze środowiskiem, w którym wydajność jest kluczowa to okrojone możliwości tablic sprawiają, że są one bardziej wydajne. Po prostu nie mają wbudowanych mechanizmów, które spowalniają ich działanie.

Podsumowanie

Tablice to podstawowe kontenery danych, które każdy programista powinien znać, zwłaszcza, że występują one w podobnej postaci w wielu językach programowania. Zrozumienie jak działają jest kluczowe do zrozumienia trochę bardziej skomplikowanych mechanizmów jakim są kolekcje. Po opanowaniu tablic i kolekcji, w większości przypadków będziesz jednak korzystał z kolekcji. Powstały one przede wszystkim po to by uprościć pracę programistów i zmniejszyć ilość pisanego przez nich powtarzalnego (boilerplate) kodu.

 

 

 

Kurs Java dla początkujących

Spis Treści:

  1. Wprowadzenie
  2. Klasy i Obiekty
  3. Tablice
  4. Kolekcje
  5. Instrukcje warunkowe i pętle
  6. Operacje wejścia i wyjścia
  7. Dziedziczenie, Polimorfizm, Interfejsy
  8. Stream’y i lambdy

 

Mateusz Dąbrowski

Cześć jestem Mateusz, zajmuję się programowaniem już ponad 12 lat z czego ponad 8 programuję w Javie. Zapraszam Cię do lektury mojego bloga. Możesz przeczytać więcej o mnie >>TUTAJ<<

2 thoughts to “Kurs Java dla początkujących – #3 Tablice”

  1. Witam.
    Przydała by się informacja, ze np:
    Arrays.toString(…) Nie zadziała, gdy piszemy kod na aplikacjach w telefonie.

    Powodem tego jest brak: java.util.Arrays
    Aby Arrays działał prawidłowo musi być wstawiony na początku przed klasa:
    import java.util.Arrays;

    Programy na PC tego nie wymagają… Chyba to jest „robione” z automatu.

    Miałem z tym problem dlatego tu pisze 😉

    Pozdrawiam.

    1. W każdym przypadku taki import jest potrzebny. Ja podałem przykłady bez importów. Jak korzystasz z IntelliJ Idea czy Android Studio, które jest oparte o IntelliJ Idea to takie importy powinny dodawać się automatycznie, a jeśli nie to środowisko powinno podpowiadać możliwość dodania takiego importu.

Komentarze są zamknięte.