Kolekcje object that groups multiple elements into a single unit
W wielu programach deklaracje typu: MyObject myreference; są uprawnione, jednak często zwłaszcza przy bardziej skomplikowanych programach nowe obiekty są kreowane w oparciu o pewne kryteria znane dopiero w czasie wykonania. Wcześniej nie jest znana ani liczba, a niekiedy nawet typ potrzebnych obiektów. W pewnym stopniu problem rozwiązuje wbudowany w Javie typ array.
Tablice Tablica (Array) to po prostu sekwencja obiektów lub wartości typu prostego opatrzona wspólną nazwą. Wszystkie elementy tablicy muszą być tego samego typu! Tablice definiujemy uŝywając nawiasów prostokątnych []: lub int[] a1; int a1[]; // zapis naturalny: a1 jest typu tablica int // styl języka C
Alokacja elementów tablicy Nie zaalokowano jeszcze miejsca dla tablicy, a1 jest referencją do tablicy. MoŜna to zrobić za pomocą wyraŝenia inicjalizującego: int[] a1 = { 1, 2, 3, 4, 5 }; int[] a1 = new [11] ; // The primitives inside //the array are automatically initialized to zero Weeble[] a; a = new Weeble[] { new Weeble(), new Weeble() };
Kontrola indeksów Tablice posiadają nieodłączne pole składowe length, które moŝna odczytywać (ale nie zmieniać) wskazujące ile elementów jest w tablicy (a1.length jest równe 5). Indeks tablicy zmienia się od 0 do length-1. Wyjście poza ten zakres generuje błąd czasu wykonania (exception). Kontrola indeksów tablic jest jednym z powodów mniejszej efektywności środowiska Java, pozwala natomiast uniknąć wielu nieprzewidzianych i trudnych do wykrycia błędów programu. Uwaga: tablica jest obiektem, nawet jeśli elementy tablicy są typu prostego.
Object[] a; // uninitialized variable Object[] b = new Object[5]; // Null references for(int i; i < b.length; i++) b[i] = new Object() ;
Tablice wielowymiarowe int[][] a1 = { { 1, 2, 3, }, { 4, 5, 6, }, }; int[][][] a2 = new int[2][2][4];
Klasa Arrays W pakiecie java.util znajduje się klasa Arrays, w której zdefiniowano szereg uŝytecznych metod statycznych. Są to cztery następujące przeciąŝone (dla typów prostych i Object) grupy: equals( ), - do porównania zawartości tablic; fill( ), do wypełnienia tablicy określoną wartością (taka sama) sort( ), do sortowania tablic; binarysearch( ), wyszukanie elementu w posortowanej tablicy. Ponadto metoda aslist( ) umieszcza elementy tablicy w kontenerze List.
Kopiowanie zawartości tablic W klasie System zdefiniowano uŝyteczną metodę słuŝącą do kopiowania zawartości tablic: void arraycopy(object src, int srcpos, Object dest, int destpos, int length)
Przykład int[] i = new int[7]; int[] j = new int[10]; Arrays.fill(i, 47); Arrays.fill(j, 99); System.arraycopy(i, 0, j, 0, i.length); // "j = //[47, 47, 47, 47, 47, 47, 47, 99, 99, 99] Oczywiście kaŝde naruszenie zakresu indeksów spowoduje wygenerowanie wyjątku. Dla tablic obiektów kopiowane są tylko referencje nie same obiekty!
Porównywanie tablic metoda Arrays.equals() Aby tablice były równe musza mieć taką samą liczbę elementów oraz odpowiadające sobie elementy muszą być równe w sensie metody equals() typu tych elementów, a dla typów prostych w sensie metody equals() odpowiednich typów opakowujących.
Porównywanie elementów tablic. Jednym z podstawowych celów projektowania programów jest separacja rzeczy, które się zmieniają od tych, które są niezmienne. Jako przykład rozwaŝmy problem sortowania. To co jest niezmienne to sam algorytm sortowania, natomiast zmienny jest sposób porównywania obiektów. Stąd zamiast wbudowywać te sposoby porównywania w róŝne procedury sortowania stosujemy rozwiązanie, w którym niezmienny fragment kodu wywołuje zmienną część (technika callback).
2 sposoby porównywania Java oferuje dwa sposoby porównywania obiektów. Pierwszy oparty jest na metodzie wprowadzonej do klasy drogą implementacji interfejsu java.lang.comparable. Interfejs ten definiuje tylko jedną metodę: int compareto(object o). Metoda ta porównuje przekazany argumentem obiekt i zwraca wartość mniejszą od zera jeśli bieŝący obiekt jest mniejszy od argumentu, zero jeśli oba obiekty są równe i wartość dodatnią jeśli obiekt jest większy od argumentu. Od implementacji metody compareto() zaleŝy co to oznacza, Ŝe obiekt jest mniejszy, równy, większy. Jeśli klasa implementuje interfejs Comparable moŝna posortować tablicę obiektów a:
public class CompType implements Comparable { int i; int j; public CompType(int n1, int n2) { i = n1; j = n2; } public String tostring() { return "[i = " + i + ", j = " + j + "]"; } public int compareto(object rv) { int rvi = ((CompType)rv).i; return (i < rvi? -1 : (i == rvi? 0 : 1)); } }
CompType[] a = new CompType[12] ; // Arrays.sort(a);
2 sposób Co jeśli klasa nie implementuje interfejsu Comparable, lub implementacja nas nie satysfakcjonuje? Rozwiązaniem moŝe być zastosowanie wzorca projektowego strategy, zgodnie z którym zmienny kod umieszczany jest w oddzielnej klasie (strategy object). Następnie do niezmiennej części algorytmu przekazujemy ten obiekt, który umoŝliwia rozwiązanie problemu. Zgodnie z tym wzorcem moŝemy zaprojektować róŝne sposoby porównywania obiektów i uzupełniać nimi niezmienny algorytm. Przy sortowaniu definiujemy klasy implementujące interfejs Comparator, w którym zdefiniowano metody: compare( ) i equals( ). PoniewaŜ implementację metody equals( ) wszystkie klasy dziedziczą po klasie Object niezbędne jest jedynie zdefiniowanie metody compare( ).
Podsumowując, sortowanie tablic zawierających obiekty jest moŝliwe jeśli implementują one interfejs Comparable lub posiadają skojarzony z nim Comparator. W obecnych wersjach API języka Java (od 1.2) klasa String implementuje interfejs Comparable co umoŝliwia leksykograficzne sortowanie tablic stringowych (z uwzględnieniem wielkości liter).
Jeśli ta reguła sortowania nie jest adekwatna do danego zastosowania to definiujemy własną klasę komparatora np. public class AlphabeticComparator implements Comparator { } public int compare(object o1, Object o2) { } String s1 = (String)o1; String s2 = (String)o2; return s1.tolowercase().compareto(s2.tolowercase());
Searching a sorted array Once an array is sorted, you can perform a fast search for a particular item by using Arrays.binarySearch( ). However, it s very important that you do not try to use binarysearch( ) on an unsorted array; the results will be unpredictable. Arrays.binarySearch( ) produces a value greater than or equal to zero if the search item is found. Otherwise, it produces a negative value representing the place that the element should be inserted if you are maintaining the sorted array by hand. The value produced is -(insertion point) - 1
Podsumowanie Podsumowując tablice są podstawowym i najefektywniejszym sposobem przechowywania grupy obiektów (i jedynym sposobem dla typów prostych). Jeśli jednak nie jest znana z góry liczba obiektów lub potrzebujemy bardziej wyrafinowanego sposobu przechowywania obiektów naleŝy skorzystać z biblioteki klas kontenerowych (Collections). Pakiet utilities zawiera zbiór klas kontenerowych znanych jako kolekcje. Kontenery te (List, Set, Map) mogą przechowywać wyłącznie typy obiektowe! Wartości typu prostego naleŝy przed umieszczeniem w kontenerze opakować (klasy Integer, Double, etc.).
Interfejsy kolekcyjne
Interface Collection public interface Collection<E> extends Iterable<E> { // Basic operations int size(); boolean isempty(); boolean contains(object element); boolean add(e element); //optional boolean remove(object element); //optional Iterator<E> iterator(); void clear(); //optional... }
Abstrakcja pojęcia TM - zbiór Set a collection that cannot contain duplicate elements. This interface models the mathematical set abstraction SortedSet a Set that maintains its elements in ascending order. Several additional operations are provided to take advantage of the ordering. HashSet, LinkedHashSet, TreeSet
List -- Sekwencja elementów List an ordered collection (sometimes called a sequence). Lists can contain duplicate elements. The user of a List generally has precise control over where in the list each element is inserted and can access elements by their integer index (position). ArrayList (Vector), LinkedList
Kolejka Queue a collection used to hold multiple elements prior to processing. Besides basic Collection operations, a Queue provides additional insertion, extraction, and inspection operations. Queues typically, but do not necessarily, order elements in a FIFO (first-in, first-out) manner. LinkedList (FIFO), PriorityQueue
Odwzorowanie klucz --> wartość Map an object that maps keys to values. A Map cannot contain duplicate keys; each key can map to at most one value. If you've used Hashtable, you're already familiar with the basics of Map. SortedMap a Map that maintains its mappings in ascending key order. HashMap, LinkedHashMap, TreeMap