Post on 20-Jan-2016
description
• Cechy kolekcji• Przegląd interfejsów i klas kolekcji• Przykłady użycia• Iteratory
Kolekcje
• Siła kolekcji leży w tym, że są zamienne – mają taki sam interfejs, a różnią się implementacją
• Są dwa podstawowe interfejsy: Collection i Map,inne interfejsy są ich rozszerzeniem
• Platforma Java zawiera różne implementacje tych samych interfejsów
• Każdą kolekcję obiektów można przejść z użyciem iteratora (uniwersalnie), lub w przewidziany tylko dla niej sposób (specyficznie)
Kolekcje w Javie przechowują grupy obiektów,wykorzystując gotowe algorytmy składowania danych
Cechy kolekcji
• Kolekcja (Collection) reprezentuje grupę obiektów (elementów)
• Zbiór (Set) jest kolekcją która nie może zawierać powtórzeń elementów
• Lista (List) jest kolekcją z ustalonym porządkiem (kolejnością) elementów, może zawierać powtórzenia
• Odwzorowanie (Map) przyporządkowuje do danych kluczy wartości, klucze nie mogą się powtarzać
Interfejsy kolekcji
• Kolekcje przechowują referencje do Object, nie są więc czułe na typ danych (gubią informację o typie)
• Przy odczycie elementów trzeba wykonywać rzutowanie do odpowiedniego typu danych
• W jednej kolekcji mogą być obiekty różnych klas (ponieważ wszystkie są zgodne z Object)
• Używając typów opakowujących (ang. wrapper types) można umieszczać w kolekcjach m.in. liczbyi pojedyncze litery
• Używając metody size() można odczytać aktualną ilość elementów w kolekcji
• Kolekcje znajdują się w pakiecie java.util
Cechy kolekcji (c.d.)
List zakupy = new ArrayList();zakupy.add("Mleko");zakupy.add("Rogalik");zakupy.add("Kakao");zakupy.add("Miód");
for (int i = 0; i < zakupy.size(); i++) {System.out.println(i + ". " + zakupy.get(i));
}
rozszerzalna tablica
Map ceny = new HashMap();ceny.put("Mleko", new Double(1.49));ceny.put("Rogalik", new Double(0.45));
System.out.println("Cena rogalika: " + ceny.get("Rogalik"));
Object[] produkty = ceny.keySet().toArray();for (int j = 0; j < produkty.length; j++) {
System.out.println(produkty[j]+" : " + ceny.get(produkty[j]));
}
odwzorowanie (mapa)
Użycie kolekcji
Inte
rfejsy
Set
List
Map
Tablicamieszająca
Rozszerzalnatablica
Zbalansowanedrzewo
Listawiązana
HashSet TreeSet
Implementacje
ArrayList LinkedList
HashMap TreeMap
Klasy kolekcji na platformie Java
• Najprostszą klasą kolekcji jest ArrayList (jest to lista zaimplementowana w postaci tablicy). Zapewnia ona szybki dostęp swobodny do elementów i potrafi automatycznie powiększać swój rozmiar. W starej bibliotece kolekcji jej odpowiednikiem jest Vector.
• Większą funkcjonalność posiada klasa LinkedList (jest to lista o szybkim dostępie sekwencyjnym do elementów). Także automatycznie powiększa swój rozmiar. Jest jednak stosunkowo powolna przy dostępie swobodnym. Posiada bardziej uniwersalny zestaw metod (np. addFirst() / addLast()).
Klasy kolekcji (c.d.)
Wybrane metody interfejsu Collection:– dodanie elementów – metoda add()– odczyt ilości elementów – metoda size()– pobranie elementu – metoda get()– ustawienie elementu – opcjonalna metoda set()– usunięcie elementu – opcjonalna metoda remove()– zwrócenie tablicy z elementami kolekcji – metoda
toArray()
Wybrane metody interfejsu Map:– dołączenie elementu do klucza – metoda put()– odczytanie elementu spod klucza – metoda get()– odczyt zbioru wszystkich kluczy – metoda keySet()– test czy klucz jest w kolekcji – metoda containsKey()– test czy element jest w kolekcji – metoda
containsValue()
Przegląd metod kolekcji
• Obiekt iteratora dla kolekcji uzyskuje się wywołując jej metodę iterator(). Jest on gotów do zwrócenia pierwszego elementu ciągu.
• Dla uzyskania następnego elementu kolekcji należy wywołać metodę next() iteratora.
• Można sprawdzić, czy są jeszcze jakieś elementyw ciągu wywołując metodę hasNext()
• Można usunąć ostatni zwrócony przez iterator element, stosując metodę remove()
Iterator jest obiektem umożliwiającym przemieszczaniesię po elementach kolekcji, niezależnie od jej struktury
Iteratory
• Użycie iteratorów pozwala korzystać z kolekcji w taki sposób, że łatwo wymienić jej implementację na inną
class Krzeslo {/* ... */
}
List sala = new ArrayList();for (int i = 1; i <= 20; i++) {
sala.add(new Krzeslo("nr. " + i));}
Iterator it = sala.iterator();while (it.hasNext()) {
Krzeslo k = (Krzeslo) it.next();System.out.println(k.odczytajNumer());
}
Kod działa równie dobrze, jeśli jest:List sala = new LinkedList();
odczyt iteratora
czy są jeszcze elementy?
przywrócenie typu(rzutowanie)
Przykład użycia iteratora
• Sytuacja błędna powoduje utworzenie nowego obiektuwyjątku i rzucenie go
• Kod, który wyrzuca wyjątki można spróbować wykonać,a pojawiające się wyjątki można łapać
• Złapany wyjątek można obsłużyć albo rzucić ponownie• Jeśli kod w metodzie rzuca wyjątek (nie jest on
obsłużony), musi być to wyspecyfikowane w deklaracji metody
• Wszystkie wyjątki pochodzą od klasy java.lang.Exception
Podstawą filozofii Javy jest założenie, że:Podstawą filozofii Javy jest założenie, że:źle sformułowany kod nie zostanie wykonanyźle sformułowany kod nie zostanie wykonany
Wyjątki
• Odbywa się z użyciem bloków try i catch.– Pierwszy blok (try – spróbuj) obejmuje kod, który może
spowodować wyjątek.– Drugi blok (catch – złap) określa jakie wyjątki chce
obsłużyć i zawiera kod z obsługą błędów.
• Jeśli wyjątek został złapany, można m.in.– wyświetlić informację o pochodzeniu błędu (jest to
najczęściej używane): e.printStackTrace()– odczytać komunikat błędu: e.getMessage()– odczytać źródło błędu: e.getCause()
Łapanie wyjątków
import java.io.*;
public class Imie {
static void odczytajImie() {BufferedReader in = new BufferedReader( new InputStreamReader(System.in));try { System.out.print("Podaj imie: "); String imie = in.readLine(); // może być wyjątek System.out.print("Witaj " + imie + "!");} catch (IOException e) { e.printStackTrace();}
}
public static void main(String[] args) {odczytajImie();
}}
blok try
lokalna obsługa wyjątku
Łapanie wyjątków – przykład (1)
import java.io.*;
public class Imie {
static void odczytajImie() throws IOException {BufferedReader in = new BufferedReader( new InputStreamReader(System.in));
System.out.print("Podaj imie: "); String imie = in.readLine(); // może być wyjątek System.out.print("Witaj " + imie + "!");}
public static void main(String[] args) {try { odczytajImie();} catch (IOException e) { e.printStackTrace();}
}}
specyfikacja wyjątku
obsługa wyjątku
blok try
Łapanie wyjątków – przykład (2)
• Aby zasygnalizować błąd, należy utworzyć obiekt wyjątku (podając przyczynę błędu)
• Następnie należy rzucić wyjątek, z użyciem słowa kluczowego throw:
long suma = 0;int iloscNieujemnych = 0;
void dodajNieujemna(int liczba) throws IllegalArgumentException {
if (liczba > 0) {suma += liczba;iloscNieujemnych++;
} elsethrow new IllegalArgumentException("liczba <= 0");
}
Rzucanie wyjątków
• Nowa klasa wyjątku powinna dziedziczyć z Exception
• Powinna deklarować przynajmniej dwa konstruktory:• bezparametrowy• z jednym argumentem typu String
• Może zawierać dodatkowe pola i metodypublic class AccessDeniedException extends Exception {public AccessDeniedException() {
super();}public AccessDeniedException(String s) {
super(s); }}
Tworzenie własnych klas wyjątków
Strumienie wejścia/wyjścia
• Typy strumieni• Łączenie strumieni dla zwiększenia
możliwości• Różne źródła i ujścia danych• Przykłady użycia
• Na podstawie dwóch logicznych operacji wyróżniamy dwa typy strumieni:– strumienie wejściowe (odczyt danych)– strumienie wyjściowe (zapis danych)
• Strumień jest zawsze stowarzyszony z jakimśźródłem danych (odczyt) lub ujściem (zapis)
• Wyróżniamy także strumienie bajtowe i znakowe
• W Javie obsługę strumieni zapewnia pakiet java.io
Strumień jest abstrakcyjną reprezentacjądowolnego źródła lub ujścia danych
Strumienie danych
informacjaźródłodanych
Programodczy
t
informacjaujście
danychProgram
zapis
strumień wyjściowy
strumień wejściowy
Strumienie wejściowe i wyjściowe
Algorytmy odczytu i zapisu
otwórz strumieńjeśli jest jeszcze informacja
odczytaj informacjęzamknij strumień
Odczyt
otwórz strumieńjeśli jest jeszcze informacja
zapisz informacjęzamknij strumień
Zapis
Algorytmy odczytu i zapisu
• Klasy strumieni są w pakiecie java.io• Przy nieudanych operacjach pojawiają
się wyjątki klasy java.io.IOException• Strumienie bajtowe i znakowe
zapewniają praktycznie taką samą funkcjonalność
Strumieniebajtowe
Strumienieznakowe
Hierarchia strumieni
Dwa najbardziej ogólne strumienie bajtowe to:• InputStream – do odczytu, oraz• OutputStream – do zapisu ciągów bajtów.
InputStream OutputStream
abstract int read() abstract void write(int b)
int read(byte[] b) void write(byte[] b)
int read( byte[] b, int off, int len)
void write( byte[] b, int off, int len)
long skip(long n) void flush()
void close() void close()
Strumienie bajtowe
Podstawowymi strumieniami znakowymi są: • Reader – do odczytu, oraz• Writer – do zapisu ciągów znaków.
Reader Writer
int read() void write(int c)
int read(char[] cbuf) void write(char[] cbuf)
abstract int read(char[] cbuf, int off, int len)
abstract void write(char[] cbuf, int off, int len)
long skip(long n) void flush()
void close() void close()
Strumienie znakowe
• Zwiększenie funkcjonalności odbywa się przez użycie wyspecjalizowanych strumieni. Korzystają onez innych strumieni, aby wykonywać swoją pracę.
BufferedReader String readLine()
InputStreamReader int read(char[] cbuf)
InputStream int read(byte[] b)
• Robi się to przez opakowanie jednego typu strumienia w inny (aby to zadziałało musi istniećw wybranej klasie odpowiedni konstruktor).
Rozszerzanie funkcjonalności
import java.io.*;public class PowielajLinie { public static void main(String[] args) throws IOException { System.out.println("Wpisuj linie tekstu. " + "Koniec gdy pusta linia.");
}}
System.innew InputStreamReader(System.in)BufferedReader in = new BufferedReader( new InputStreamReader(System.in));
String linia;do { linia = in.readLine(); System.out.println(linia);} while (linia.length() > 0);
InputStream
Odczyt standardowego wejścia
Zamiana strumieni bajtowych na znakowe:• InputStreamReader /
OutputStreamWriter
Odczyt i zapis z uwzględnieniem znaków końca linii:
• BufferedReader – readLine()• BufferedWriter – newLine()
Strumień z buforem (większa wydajność):• BufferedInputStream /
BufferedOutputStream
Przeciążone metody println():• PrintStream / PrintWriter
Strumienie wyspecjalizowane
Odczyt i zapis tablic bajtów lub znaków (w pamięci):• ByteArrayInputStream /
ByteArrayOutputStream• CharArrayReader / CharArrayWriter
Odczyt i zapis łańcuchów napisów (w pamięci):• StringReader / StringWriter
Odczyt i zapis plików:• FileInputStream / FileOutputStream• FileReader / FileWriter
Serializacja obiektów:• ObjectInputStream / ObjectOutputStream
Strumienie wyspecjalizowane
• Żeby otworzyć plik, wystarczy stworzyć obiekt wybranej klasy, podając nazwę pliku w postaci łańcucha znaków lub obiektu klasy File FileInputStream – odczyt pliku
binarnego FileOutputStream – zapis pliku binarnego
(*) FileReader – odczyt pliku znakowego FileWriter – zapis pliku znakowego (*)(*) możliwe otwarcie pliku do dopisywania, bez
usuwania poprzedniej zawartości
• Otwarty strumień można opakować w wybrany strumień wyspecjalizowany
• Po zakończeniu strumień należy zamknąć – close()
Odczyt i zapis plików
• NIE JEST to plik – służy raczej jako OPIS ŚCIEŻEK do plików lub katalogów:
• Przy użyciu tej klasy można także m.in.– sprawdzać informacje o pliku: isDirectory(),
isFile(), canRead(), canWrite(), exists(), length(), lastModified()
– wykonywać operacje na plikach i katalogach: (delete(), mkdir(), mkdirs(), renameTo()
– odczytywać zawartość katalogu: list(), listFiles()
File plik = new File("plik.txt");FileReader in = new FileReader(plik);
Klasa File