Programowanie Obiektowe (Java) Wykład ósmy 1.

Wprowadzenie do kontenerów Kontenery są obiektami, które potrafią przechowywać inne obiekty w określony sposób. O kontenerach można myśleć jako o gotowych do użycia strukturach danych. W języku Java istnieją kontenery pozwalające np.: przechowywać obiekty w postaci listy wiązanej lub w postaci drzewa. Mechanizm działania takich obiektów jest ukryty przed ich użytkownikami (czyli również przed nami). Jedyne czym dysponuje programista korzystający z kontenerów jest ich interfejs i dokumentacja do niego dostarczona wraz ze środowiskiem Javy. Stosując kontenery należy pamiętać, że nie przechowują one wprost obiektów, tylko referencje do nich. Referencje te nie są takiej klasy jak umieszczane w kontenerze obiekty, ale klasy Object. Oznacza to, ze umieszczając obiekt w kontenerze tracimy informacje o jego klasie. Wszystkie kontenery w języku Java dzielą się na dwa rodzaje opisane dwoma różnymi interfejsami. Pierwszym rodzajem kontenerów są kolekcje. Ich typ jest określony interfejsem Collection. Kontenery te zazwyczaj przechowują obiekty wedle jakiejś określonej reguły, np.: zbiory przechowują tylko różne elementy, przy czym można określić którą cechą mają się one różnić, a listy przechowują obiekty w określonym porządku. Drugi rodzaj stanowią odwzorowania, określone interfejsem Map. Odwzorowania przechowują pary obiektów, postaci klucz wartość. Zapoznajmy się na początek z metodami, jakie są zadeklarowane w interfejsie Collection: boolean add(Object) nie powiedzie,

jest metodą opcjonalną, służy do dodawania obiektu do kontenera, zwraca wartość false jeśli ta operacja się

boolean addAll(Collection) również jest metodą opcjonalną, jej działanie polega na dodaniu do kontenera wszystkich elementów, znajdujących się w kolekcji przekazanej jej przez parametr, zwraca wartość false jeśli żaden z obiektów nie zostanie dodany, void clear() - podobnie jak poprzedniczki jest opcjonalna, usuwa wszystkie obiekty z kontenera, boolean contains(Object)

zwraca wartość true jeśli w kontenerze znajduje się obiekt do którego została przekazana jej referencja,

boolean containsAll(Collection) podobnie jak poprzedniczka, ale sprawdza nie pojedynczy obiekt, a wszystkie obiekty należące do podanej jej przez parametr kolekcji, boolean isEmpty() - sprawdza, czy kontener jest pusty, jeśli tak to zwraca wartość true, Iterator iterator() - zwraca referencję do obiektu kontenera,

iteratora, pozwalającego „poruszać się” po obiektach wchodzących w skład

boolean remove(Object) jeśli obiekt, którego referencja została tej metodzie przekazana przez parametr, znajduje się w w kontenerze, to jest on usuwany i zwracana jest wartość true, jest metodą opcjonalną, boolean removeAll(Collection) metodą opcjonalną,

usuwa wszystkie obiekty, z kontenera, które należą do przekazanej jej przez parametr kolekcji, jest

boolean retainAll(Collection) zatrzymuje w kontenerze te obiekty, które należą również od kolekcji przekazanej jej przez parametr, jest metodą opcjonalną, int size() - zwraca liczbę obiektów umieszczonych w kontenerze, Object[] toArray() - zwraca tablicę referencji do wszystkich obiektów z kontenera, Object[] toArray(Object[] a) zwraca tablicę referencji do wszystkich obiektów umieszczonych w kontenerze, typ referencji jest taki sam jak typ elementów tablic przekazanej przez parametr. Interfejs Collection jest rozszerzany przez dwa inne interfejsy: List i Set. Interfejs List określa metody pozwalające na przechowywanie obiektów w kontenerze w określonym porządku. Ten interfejs jest implementowany przez dwie klasy: ArrayList, która pozwala na szybki dostęp do przechowywanych obiektów, ale operacje wstawiania i usuwania obiektów dla tego kontenera są stosunkowo wolne. Klasa LinkedList pozwala stosunkowo szybko wstawiać i usuwać elementy z kontenera, natomiast przeglądanie zgromadzonych w niej obiektów jest stosunkowo wolne. Na bazie LinkedList można budować stosu i kolejki. Oto przykład ilustrujący użycie tych dwóch klas: import java.util.*;

W kontenerach klasy LinkedList i ArrayList będziemy umieszczać obiekty klasy Element. Klasa ta posiada pole prywatne o nazwie value, konstruktor z parametrem, który inicjalizuje to pole oraz nadpisuje metodę toString(). W metodzie main klasy publicznej Listy tworzymy dwa obiekty będące kontenerami, pierwszy klasy ArrayList, a drugi klasy LinkedList. Tworzymy też referencję, której typ jest określony interfejsem Iterator. Obiekty, których klasy implementują taki interfejs są obiektami lekkimi (koszt ich tworzenia jest mały) i pozwalają w uniwersalny sposób poruszać się po obiektach umieszczonych w dowolnym kontenerze. Iterator podstawowy posiada trzy metody: next() - zwraca adres kolejnego obiektu w kontenerze, hasNext() - sprawdza, czy są jeszcze jakieś nieodwiedzone obiekty w kontenerze oraz remove() - usuwa obiekt z kontenera. Istnieją bardziej specjalizowane kontenery dla niektórych rodzajów kontenerów. Pierwszą czynnością wykonywaną w programie jest dodanie do kontenera klasy ArrayList 20 obiektów klasy Element, które będą przechowywać wartości całkowite z przedziału od 0 do 19. Następnie zawartość całego kontenera jest wypisywana na ekran. Java posiada przeciążone wersje metod print() i

class Element { private int value;

public String toString() { return new Integer(value).toString(); }

public Element(int x) { value=x;

1

Programowanie Obiektowe (Java) println(), które pozwalają bezpośrednio wypisać obiekty należące do kontenera (dla każdego takiego obiektu wywoływana jest metoda toString(), dlatego została ona przeciążona w klasie Element). W kolejnej pętli for zawartość kontenera jest ponownie wypisywana na ekran. Tym razem jednak pobieramy z kontenera klasy ArrayList adres każdego z przechowywanych w niej obiektów, za pomocą określonej w tej klasie metody get(indeks) i dopiero po jego uzyskaniu przekazujemy ten obiekt do metody println(). Kolejne wiersze programu pokazują w jaki sposób możemy posługiwać się iteratorem. Najpierw musimy uzyskać taki iterator wywołując metodę iterator() kontenera ArrayList. Następnie w pętli while przechodzimy przez kolejne elementy należące do tego kontenera i wypisujemy je na ekran. Następnie ponownie uzyskujemy iterator, przechodzimy nim po obiektach zgromadzonych w kontenerze klasy ArrayList, wstawiamy je za pomocą metody addFirst() do kontenera klasy LinkedList i usuwamy z kontenera klasy ArrayList.1 Na zakończenie wykorzystując wykorzystujemy metody isEmpty() i removeLast() do wypisania na ekran i usunięcia obiektów z kontenera LinkedList.

} }

public class Listy { public static void main(String[] args) { ArrayList a = new ArrayList(); LinkedList l = new LinkedList(); Iterator it;

for(int i=0;i