Poprzednio poznaliśmy podstawowe typy danych w Javie. W tym wpisie pokażemy jak można posługiwać się w wygodny sposób wieloma elementami tego samego typu. Na koniec zapoznamy się z ważną klasą, która pozwala obsługiwać łańcuchy znakowe. Ich znajomość oraz umiejętność manipulowania nimi jest jednym z najważniejszych etapów szkolenia i należy do zdecydowanych podstaw.
Tablice są strukturą danych określonego typu, której elementy zajmują kolejne miejsce w pamięci – każdy tyle samo. Ta cecha pozwala do tworzenia kolekcji określonego typu.
1 2 |
int [] tablica; //deklaracja zmiennej tablicowej int [] tablica = new int[n]; //inicjacja zmiennej tablicowej o rozmiarze n |
Operator [] umożliwia pobranie lub wpisanie wartości do miejsca wyznaczonego przez indeks z przedziału od 0 do n-1, gdzie n jest rozmiarem struktury (n >= 0). Nigdy nie należy przekraczać rozmiarów tablicy, gdyż spowoduje to wyjątek typu unchecked IndexOutOfBoundException
. Dokładne znaczenie wystąpienia wyjątku wyjaśni się dalej w szkoleniu, jednakże zachęcamy choćby do pobieżnego zapoznania się z materiałem z linku.
Jeśli nie mamy pewności jaki jest rozmiar tablicy należy użyć metody length()
, która zwraca rozmiar tablicy. Jeżeli logika programu na to pozwala można też zastosować nowy typ pętli typu for each. Dzięki jej użyciu nie ma potrzeby uważania na indeksy tablicy.
1 |
tablica.length() // zwróci rozmiar tablicy |
Należy pamiętać, że zmienna tablicowa jest tak naprawdę referencją. Etykieta wskazuje miejsce w pamięci. W związku z tym gdy użyjemy poleceń:
1 2 |
int [] liczby = {1,2,3,4,5}; int [] numery = liczby; |
tak naprawdę przypiszemy do zmiennej tablicowej numery referencję do tej samej tablicy, która znajduje się pod adresem wskazanym przez zmienną liczby. Rysunek poniżej zobrazuje podane polecenia.
Te tablice są w rzeczywistości tablicami, które wskazują na tablice. Deklaracja i dostęp do nich odbywa się w podobny sposób jak w przypadku tablicy jednowymiarowej – wystarczy użyć dwóch operatorów [].
1 2 3 4 5 |
int [][] tabela = new tabela[n][m]; int [][] tabela = { {1,1,1}, {2,2,2} }; |
Do działań z tablicami przydają się metody z klasy Arrays
. Poniżej znajduje się lista kilku najważniejszych metod z dokumentacji. Wszystkie są statyczne, co oznacza, że wywołując je posługujemy się nazwą klasy, a nie instancją obiektu.
byte copyOf(byte[] originalTab, int newLength)
– zwraca kopię tablicy originalTab o rozmiarze podanym w parametrze newLength.void sort(T[] a)
– sortuje tablicę stosując algorytm QuickSort.String toString(typ a)
– w zależności od typu tablicy wypisuje wszystkie elementy tablicy ujęte w nawias kwadratowy, rozdzielone przecinkami.boolean equals(typ [] a, typ [] b)
– sprawdza czy tablice są tego samego rozmiaru i odpowiednie elementy są tej samej wartości.void fill(typ [] a, typ v)
– ustawia wszystkie elementy tablicy wartością v – pozwala to zaoszczędzić czas gdy chcemy wypełnić całą tablicę jedną wartością.Łańcuchy znakowe służą do przechowywania danych tekstowych. Ich poprawna obsługa jest kluczowa w wielu dziedzinach programowania dlatego warto dobrze poznać tę klasę. Oprócz prostych komunikatów, które wyświetlimy użytkownikowi w oknie konsoli, pozwalają na przechowywanie danych, takich jak nazwy, opisy, polecenia SQL, czy też ścieżki dostępu do plików.
W niektórych językach np. PHP typ String
jest wbudowany. W Javie String
jest elementem biblioteki standardowej, która zawiera klasę o tej nazwie. Zwróćmy uwagę, że po raz pierwszy użyjemy innej klasy niż ta, w której znajduje się nasza metoda main()
.
Programistom przyzwyczajonym do korzystania z łańcuchów np. w języku C polecamy jak najszybciej przestawić się na korzystanie z klasy String
. Posiada on wiele zalet, a podstawową jest zwolnienie obowiązku pilnowania czy łańcuch jest odpowiednio duży, aby pomieścić tekst. Używanie łańcuchów w Javie jest niezwykle proste. Poniżej znajduje się porównanie podejścia łańcuchowego znanego z C oraz klasa String
z Javy.
1 2 |
char [] imie = new char[] {'K', 'a', 'm', 'i', 'l'}; //łańcuch znakowy z C String imie = „Kamil” //obiekt klasy String z Javy |
Kolejnym argumentem jest też wygoda uzupełniania danych – dużo prościej przypisać literał do obiektu klasy String niż wypełniaj każdy element tablicy osobnym znakiem.
W obu przypadkach obiekty składają się ze znaków (w przypadku Javy Unicode), natomiast w C tablica posiada z góry zadeklarowany rozmiar – 20 znaków. W związku z tym imię nie może przekroczyć tego rozmiaru gdyż konsekwencją może być awaryjne wyście z programu lub w najlepszym przypadku praca z nieprawidłowymi danymi. Klasa String
nie posiada tych ograniczeń i nie jesteśmy zmuszeni, aby z góry przewidzieć ile maksymalnie znaków zostanie użytych.
Z drugiej strony czy problemem byłoby zadeklarować tablicę o większym rozmiarze np. 1000 znaków? Oczywiście można tak zrobić, ale jeżeli imię składa się z 4 liter, to zużyjemy niepotrzebnie wiele pamięci komputera.
Kolejną zaletą klasy String
jest cały szereg metod, które dostarcza. Poniżej wypiszemy najważniejsze z nich (wszystkie są wymienione w dokumentacji dostępnej w internecie).
int length()
– długość łańcucha.String toLowerCase()
– zwraca łańcuch, w którym wszystkie znaki zostają zastąpione małymi literami.String toUpperCase()
– zwraca łańcuch, w którym wszystkie znaki zostają zastąpione dużymi literami.boolean equals(Object other)
– sprawdza czy łańcuch jest identyczny z łańcuchem other. Warto zwrócić uwagę na to, że obiekt other jest klasy Object
czyli klasy, która jest nadrzędna dla wszystkich klas w Javie – to właśnie ona zawiera metodę equals()
, ale o tym napiszemy w następnych rozdziałach.String replace(CharSequence oldString, CharSequence newString)
– zwraca łańcuch, w którym wszystkie wystąpienia łańcucha oldString zostają zastąpione łańcuchem newString.String substring(int beginIndex)
– zwraca łańuch, który zaczyna się od beginIndex.boolean equalsIgnoreCase(String other)
– sprawdza czy łańcuch jest identyczny z other ignorując wielkość znaków.String substring(int beginIndex, int endIndex)
– sprawdza łańcuch, który zaczyna się od beginIndex, a kończy na endIndex.String trim()
– zwraca kopię łańcucha bez wiodącego i znajdującego się na końcu ciągu białego znakuOprócz metod należy zwrócić uwagę na konkatenację łańcuchów operatorem „+”. Jest to jedyny przeciążony operator w Javie. Używa się go tak samo jak znaku „dodać” przy działaniach arytmetycznych. Tak samo z operatorem przypisania. Poniżej przedstawimy omawiane sytuacje.
1 2 3 4 5 6 |
String str1 = „Witaj”; String str2 = „na kursie łańcuchów w Javie”; String str3 = „”; System.out.println(str1 + „ „ +str2); //konkatenacja łańcuchów – wynik – Witaj na kursie Javy str3 = str1 + str2; //łańcuchy str1 i str2 pozostaną niezmodyfikowane, a str3 będzie łańcuchem złożonym z str1 i str2 w kolejności podanej od lewej strony |
W przypadku, łączenie wielu łańcuchów w jeden obiekt typu String warto rozważyć użycie specjalnego obiektu klasy StringBuffer
lub StringBuilder
.
Co jednak gdy chcemy porównać dwa łańcuchy? Czy można użyć operatora == znanego z poprzedniej części? Innymi słowy czy wynik porównania str3 == str1 + str2? Odpowiedź brzmi nie, ponieważ nazwy obiektów wskazują miejsce w pamięci (referencja) i to one zostaną porównane zatem ta operacja zwróci prawdę tylko w przypadku gdy porównamy ten sam łańcuch, a nie możemy nigdy założyć, że tak będzie. Aby otrzymać wynik prawidłowy należy użyć metody equals()
.
1 |
Str3.equals(str1 + str2); //wynik prawdziwy |
W następnym wpisie przyjrzymy się pętlom oraz przepływom sterowania.
About the author