Spis treści
Prędzej czy później będziemy w naszych programach potrzebowali porównać ze sobą dwie tablice, by odpowiedzieć na pytanie, czy zawierają takie same elementy. Spróbujmy porównać dwie tablice za pomocą operatora ==:
public class PorownywanieTablicOperatorRownosci { public static void main(String[] args) { int[] pierwszaTablica = { 10, 5, 20 }; int[] drugaTablica = { 10, 5, 20 }; if (pierwszaTablica == drugaTablica) { System.out.println("Tablice sa takie same."); } else { System.out.println("Tablice nie sa takie same."); } } }
Ku potencjalnemu zdziwieniu, na ekranie zobaczymy komunikat:
Tablice te mają co prawda takie same elementy, lecz każda z nich jest osobnym obiektem. Tablice to typy referencyjne (złożone), podobnie jak typ String, a w przeciwieństwie do ośmiu poznanych już typów podstawowych (int, boolean, double itd.). O typach referencyjnych będziemy bardzo dużo mówić zaczynając od rozdziału o klasach. Na razie zapamiętajmy, że nie powinniśmy porównywać tablic za pomocą operatora == bądź !=.
W przypadku typu String, wartości należy porównywać za pomocą metody equals, jednakże porównywanie dwóch tablic musimy wykonać w inny sposób. Aby sprawdzić, czy dwie tablice mają takie same wartości (i w takiej samej kolejności), musimy skorzystać z pętli i przejść przez wszystkie elementy tablic i porównać je ze sobą:
public class PorownajTablice { public static void main(String[] args) { int[] pierwszaTablica = { 10, 5, 20 }; int[] drugaTablica = { 10, 5, 20 }; // jezeli tablice maja rozne rozmiary, // to na pewno nie bede takie same if (pierwszaTablica.length != drugaTablica.length) { System.out.println("Tablice nie sa takie same."); } else { boolean czyRoznicaZnaleziona = false; for (int i = 0; i < pierwszaTablica.length; i++) { // sprawdzamy, czy elementy o tych samych indeksach roznia // sie wartoscia - jezeli znajdziemy choc jedna roznice, // to bedziemy wiedziec, iz tablice nie sa takie same if (pierwszaTablica[i] != drugaTablica[i]) { czyRoznicaZnaleziona = true; break; } } if (czyRoznicaZnaleziona) { System.out.println("Tablice nie sa takie same."); } else { System.out.println("Tablice sa takie same."); } } } }
Jak widać, jest dużo więcej zachodu z porównywaniem dwóch tablicy, niż można się było spodziewać.
Najpierw sprawdzamy rozmiar obu tablic – jeżeli tablice mają różną liczbę elementów, to na pewno nie będą takie same. Jeżeli rozmiar się zgadza, w pętli przechodzimy przez wszystkie elementy tablic i porównujemy elementy o tych samych indeksach – jeżeli znajdziemy chociaż jedną parę elementów, które się różnią, będzie to oznaczało, że tablice nie są takie same – możemy w takim przypadku skorzystać z instrukcja break, by zakończyć pętlę. Na końcu programu, na podstawie wartości zmiennej czyRoznicaZnaleziona, wypisujemy informację, czy tablice są takie same, czy nie. Na ekranie w tym przypadku zobaczymy:
W rozdziale o klasach dowiemy się dokładnie o różnicach pomiędzy typami referencyjnymi (złożonymi), a ośmioma typami podstawowymi (int, boolean, char itd.). Na razie zapamiętajmy, że aby porównać zawartość dwóch tablic, musimy skorzystać z pętli i porównać ze sobą elementy obu tablic na odpowiednich indeksach.
Dla dociekliwych
Zmienne typu referencyjnego wskazują na obiekty w pamięci – nie są konkretnie tymi obiektami, które zostały utworzone – w przykładzie powyżej, zmienna pierwszaTablica to nie tablica trzech elementów, lecz wskazanie na obiekt w pamięci, który jest tablicą trzech elementów typu int. Podobnie ze zmienną drugaTablica. Obie zmienne wskazują na dwa różne obiekty w pamięci – dlatego próba ich porównania za pomocą operatora == zwraca false, ponieważ obie tablice są różnymi obiektami w pamięci, tzn. nie są tym samym obiektem. W rozdziale o klasach dowiemy się dużo więcej o typach referencyjnych (złożonych), ich cechach, sposobie użycia, oraz tworzenia.
Zmiana rozmiaru tablicy¶
Wiemy już, że możemy utworzyć tablicę za pomocą słowa kluczowego new – albo podając, ile elementów tablica będzie mogła przechowywać, albo, bez podawania rozmiaru tablicy, podać elementy, z których tablica ma się składać:
int[] calkowite = new int[10]; double[] rzeczywiste; rzeczywiste = new double[] { 3.14 , 2.44, 0.99 };
Wiemy już także, że tablice mają określony w trakcie ich tworzenia rozmiar, który możemy sprawdzić używając atrybutu length.
Czasem może się zdarzyć, że będziemy potrzebowali zwiększyć rozmiar tablicy, jednakże rozmiaru raz utworzonej tablicy w trakcie działanie programu zmienić się nie da. Jest jednak możliwe rozwiązanie: możemy utworzyć nową tablicę o większym rozmiarze i przepisać do niej elementy z poprzedniej tablicy, a następnie przypisać nową tablicę do zmiennej, która poprzednio wskazywała na tablicę z mniejszą liczbą elementów:
public class NowaTablicaZWiekszaLiczbaElementow{ public static void main(String[] args) { int[] liczby = { 10, 100, -5 }; System.out.println("Elementy tablicy liczby:"); for (int x : liczby) { System.out.print(x + ", "); } System.out.println(); // przejdz do nowej linii // tworzymy druga tablice o wiekszym rozmiarze int[] tymczasowaTabela = new int[5]; // przepisujemy elementy z pierwszej tablicy for (int i = 0; i < liczby.length; i++) { tymczasowaTabela[i] = liczby[i]; } // ustawiamy dodatkowe elementy tymczasowaTabela[3] = 20; tymczasowaTabela[4] = 1; // przypisujemy druga tablice do pierwszej liczby = tymczasowaTabela; System.out.println("Elementy tablicy liczby:"); for (int x : liczby) { System.out.print(x + ", "); } } }
W tym programie utworzyliśmy tablicę o trzech elementach, dostępną za pomocą zmiennej o nazwie liczby, i wypisaliśmy jej zawartość na ekran.
Następnie, dla przykładu, w powyższym programie symulujemy potrzebę posiadania tablicy o większej liczbie elementów – tworzymy więc nową tablicę tymczasowaTablica, która może przechowywać 5 elementów. Następnie, w pętli przepisujemy wartości z mniejszej tablicy do większej.
Po wykonaniu pętli, ustawiamy dwa ostatnie elementy nowej tablicy przykładowymi wartościami. W końcu, w podświetlonej linii kodu, ustawiamy zmienną liczby, by wskazywała na nowo utworzoną tablicę. Na końcu programu ponownie wypisujemy elementy tej tablicy – tym razem widzimy pięć liczb:
W ten sposób, tablica liczby może teraz przechowywać pięć elementów, chociaż na początku programu mogła przechowywać tylko trzy elementy – a przynajmniej tak by się mogło wydawać. Oryginalna tablica trój-elementowa się nie zmieniła – to, co osiągnęliśmy w tym programie, to utworzenie nowej tablicy o większej liczbie elementów, oraz ustawiliśmy zmienną liczby, by na nią wskazywała. Wynika to z faktu, że tablice są przykładem typów referencyjnych (złożonych), o których dokładnie sobie opowiemy w rozdziale o klasach.
Dla dociekliwych
W poprzednim podrozdziale dowiedzieliśmy się, że porównywać tablice powinniśmy poprzez sprawdzenie ich rozmiarów i elementów, a nie operatora ==. Jednakże, gdybyśmy teraz porównali tablice liczby oraz tymczasowaTabela za pomocą operatora ==, to zwróciłby on wartość true! Powodem jest to, że obie zmienne wskazują teraz na ten sam obiekt w pamięci. W rozdziale o klasach wyjaśnimy sobie dokładnie to zachowanie.