Kolekcje (3) Zbiory. Porównywanie i porządkowanie elementów kolekcji. (c) Krzysztof Barteczko 2014.

Slides:



Advertisements
Podobne prezentacje
ALGORYTMY I STRUKTURY DANYCH
Advertisements

C++ wykład 4 ( ) Przeciążanie operatorów.
Klasy i obiekty.
Wzorce.
Języki programowania C++
Sposoby implementacji asocjacji
Kamil Łącki Dominik Strzelichowski
Implementacja ekstensji klasy
Implementacja asocjacji
Materiały do zajęć z przedmiotu: Narzędzia i języki programowania Programowanie w języku PASCAL Część 5: Typy porządkowe, wyliczeniowe i okrojone. Definiowanie.
Czytanie, pisanie i rysowanie – cd.. Jeszcze jeden strumyk PrintStream działa jak PrintWriter, ale: Używa domyślnego (systemowego) kodowania Nie wyrzuca.
1 Języki i techniki programowania prowadzący dr Grzegorz Filipczyk.
Tablice tablica jest sekwencją elementów tego samego typu (prostego lub obiektowego) w Javie tablice są obiektami, a zmienne tablicowe przechowują referencję
Techniki i języki programowania
Pakiety w Javie Łukasz Smyczyński (132834). Czym są pakiety? Klasy w Javie są grupowane w pewne zbiory zwane pakietami. Pakiety są więc pewnym podzbiorem.
Programowanie urządzeń mobilnych – wykład IV
Zbiór do posortowania mieści się w pamięci
Podstawy inżynierii oprogramowania Zofia Kruczkiewicz
PIO 3_2, Zofia Kruczkiewicz1 Wykład 3 – część druga Iteracyjno-rozwojowy cykl oprogramowania 3.
Złożone typy danych Listy Tworzenie elastycznych baz danych
JAVA c.d.. Instrukcji wyboru SWITCH używamy, jeśli chcemy w zależności od wartości pewnego wyrażenia wykonać jeden z kilku fragmentów kodu. Jest to w.
Programowanie obiektowe III rok EiT
Andrzej Repak Nr albumu
Java – coś na temat Klas Piotr Rosik
Inicjalizacja i sprzątanie
Seminarium problemowe
Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21 Dariusz Wardowski.
Programowanie obiektowe Wykład 6 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/14 Dariusz Wardowski.
Tworzenie Aplikacji Internetowych dr Wojciech M. Gańcza 8.
Programowanie obiektowe 2013/2014
  ELEMENTY JĘZYKA JAVA komentarze w Javie, słowa kluczowe i operatory, proste typy danych, tablice, podstawowy zestaw instrukcji.
Prasek Aneta, Skiba Katarzyna. Funkcje stałe const to takie funkcje, które nie mogą modyfikować stanu obiektu. Oznacza to, że funkcja stała nie może zmieniać.
OCPJP Inner classes.
BJUG_1: Typy Generyczne, Kolekcje
Treści multimedialne - kodowanie, przetwarzanie, prezentacja Odtwarzanie treści multimedialnych Andrzej Majkowski informatyka +
Programowanie strukturalne i obiektowe C++
Kurs języka C++ – wykład 4 ( )
PROGRAMOWANIE W JAVA Informatyka Stosowana – ROK II / III Laboratoria mgr inż. Krzysztof Bzowski.
Klasy kolekcji Tomasz Wilczyński. Kolekcja Schemat kolekcji Javy zawiera sześć interfejsów oraz kilka innych implementacji tych interfejsów do celów ogólnych.
PIO 3_2, Zofia Kruczkiewicz1 Wykład 3 – część druga Iteracyjno-rozwojowy cykl oprogramowania 3.
Programowanie Zaawansowane
Object-relational mapping (aka O/RM, ORM, and O/R mapping)
Mapa STL – C++. Problem polega na tym, że najczęściej chcielibyśmy przechowywać w zbiorze elementy jakiegoś bardziej złożonego typu, których on nie będzie.
Kolekcje (4) Mapy Widoki i algorytmy (c) Krzysztof Barteczko 2014.
Elementy programowania funkcyjnego w Javie 8. Pragmatyczny przegląd. (c) Krzysztof Barteczko 2014.
Typy i metody sparametryzowane (generics) (c) Krzysztof Barteczko 2014.
Asocjacja,Kompozycja,Agregacja
Implementacja asocjacji (z atrybutami i bez) przy użyciu: referencji (kolekcji referencji) tablic asocjacyjnych przygotował: Kamil Kowalczyk.
InMoST, Java – przykładowa aplikacja Bartosz.Michalik
Wprowadzenie do języka Java Kolekcje w języku Java Bartosz Walter.
Programowanie Obiektowe – Wykład 6
Przypomnienie wiadomości – kilka zadań
Strumienie, Wczytywanie, Zapisywanie, Operacje na plikach
Typy wyliczeniowe, kolekcje
Listy.
Wątki, programowanie współbieżne
(według:
(c) Krzysztof Barteczko 2014
Programowanie obiektowe II
Delegaty Delegat to obiekt „wiedzący”, jak wywołać metodę.
Programowanie Obiektowe – Wykład 2
Klasy wewnętrzne. Praktyka użycia interfejsów i klas wewnętrznych
Iteracyjno-rozwojowy cykl oprogramowania 3
Programowanie obiektowe – zastosowanie języka Java SE
PGO Interfejsy Michail Mokkas.
PGO - Projektowanie i implementacja pierwszych klas
ALGORYTMY I STRUKTURY DANYCH
PGO Dziedziczenie Michail Mokkas.
PGO Porównywanie obiektów
Zapis prezentacji:

Kolekcje (3) Zbiory. Porównywanie i porządkowanie elementów kolekcji. (c) Krzysztof Barteczko 2014

Istota zbioru Skoro zbiór nie może zawierać duplikatów, to przy dodawaniu elementu do zbioru musi nastąpić sprawdzenie czy zbiór nie zawiera już dodawanego elementu. Ponieważ operacji dodawania elementów do zbioru może być bardzo dużo, to wyszukiwanie elementów w zbiorze musi być szybkie, efektywne. Są przynajmniej dwa sposoby efektywnego wyszukiwania danych. Pierwszy (użycie tablicy mieszającej, inaczej: haszującej) jest zrealizowany w klasie HashSet. Drugi (wyszukiwanie binarne z użyciem drzewa czerwono-czarnego) - w klasie TreeSet.

(c) Krzysztof Barteczko 2014 Tablica mieszania (haszująca) Tablica mieszania (hashtable) jest tablicą specjalnie przystosowaną do szybkiego odnajdywania elementów. Dla każdego elementu danych wyliczany jest kod numeryczny (liczba całkowita) nazywany kodem mieszania (hashcode), na podstawie którego obliczany jest indeks w tablicy, pod którym będzie umieszczony dany element. Zwykle wyliczenie indeksu odbywa się poprzez uzyskanie reszty z dzielenia hash- kodu przez aktualny rozmiar tablicy. Może się zdarzyć, że kilka elementów otrzyma ten sam indeks (albo na skutek tego, że hash-kody są takie same, albo ze względu na to, że reszta z dzelenia przez rozmiar tablicy jest taka sama). Zatem w tablicy mieszania pod konkretnym indeksem powinna znajdować się struktura danych, która może zawierać wiele elementów, które otrzymały ten sam indeks. Taka struktura nazywa się kubelkiem (bucket) lub koszem (bin). W najprostszym przypadku strukturą tą będzie lista.

(c) Krzysztof Barteczko 2014 Tablica mieszania - ilustracja W Javie można wyliczyć kod mieszania dla każdego obiektu za pomocą zastosowania metody hashCode() z jego klasy. Metoda ta winna zwracać numeryczny kod na podstawie "treści" obiektu, np. napisu stanowiącego "zawartość" obiektu klasy String. Dwa takie same napisy będą miały te same kody mieszania. Napisy "a", "b", "c", "d", "e", "f'", "g", "h", "i" będą umieszczone w tablicy o 7 kubełkach, same kubełki natomiast będą stanowić listy elementów. a kod: 97 indeks: 6 b kod: 98 indeks: 0 c kod: 99 indeks: 1 d kod: 100 indeks: 2 e kod: 101 indeks: 3 f kod: 102 indeks: 4 g kod: 103 indeks: 5 h kod: 104 indeks: 6 i kod: 105 indeks: 0

(c) Krzysztof Barteczko 2014 Potrzebne i hashCode i equals

(c) Krzysztof Barteczko 2014 Ważne! Zarówno hashCode() jak i equals() są dobrze zdefiniowane w standardowych klasach Javy. Tworząc własne klasy musimy sami zadbać o właściwe zdefiniowanie metod int hashCode() i boolean equals(Object).

(c) Krzysztof Barteczko 2014 Standardowe definiowanie hashCode i equals Uwaga: zastosowanie instanceof zamiast getClass w equals będzie dopuszczać porównanie z obiektami w hierarchii dziedziczenia, a wtedy nie można napisac equals tak by spełniała warunki relacji równowazności.

(c) Krzysztof Barteczko 2014 Narzędzia IDE public class Employee { private String lastName; private String firstName; private int salary; public Employee(String fn, String ln, int sal) { lastName = ln; firstName = fn; salary = sal; } public String getLastName() { return lastName; } public String getFirstName() { return firstName; } public int getSalary() { return salary; } public String toString() { return firstName + " " + lastName + " " + salary; }

(c) Krzysztof Barteczko 2014 Wynik public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); return result; } public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Employee other = (Employee) obj; if (firstName == null) { if (other.firstName != null) return false; } else if (!firstName.equals(other.firstName)) return false; if (lastName == null) { if (other.lastName != null) return false; } else if (!lastName.equals(other.lastName)) return false; return true; }

(c) Krzysztof Barteczko 2014 Skutki

(c) Krzysztof Barteczko 2014 Jak postępować?

(c) Krzysztof Barteczko 2014 Porządek (1)

(c) Krzysztof Barteczko 2014 Porządek (2) Klasa LinkedHashSet udostępnia wygodną właściwość: zachowania porządku, w jakim elementy dodane były do zbioru. Gdyby w poprzednim fragmencie zmienić HashSet na LinkedHashSet: Set set = new LinkedHashSet<>(elist); System.out.println(set); to wynik wyglądałby inaczej: [Jan Kowalski 3500, Jan Malinowski 3500, Adam Kowalski 5700]

(c) Krzysztof Barteczko 2014 Porządek (3)

(c) Krzysztof Barteczko 2014 Skąd wiadomo jaki ma być porządek? Set tset = new TreeSet<>(elist); System.out.println(tset); Exception in thread "main" java.lang.ClassCastException: sets.Employee cannot be cast to java.lang.Comparable

(c) Krzysztof Barteczko 2014 Naturalny porządek

(c) Krzysztof Barteczko 2014 Naturalny porządek - przykład

(c) Krzysztof Barteczko 2014 Komparator Uporządkowane według różnych kryteriów, np. raz według nazwisk i imion, a innym razem według pensji?

(c) Krzysztof Barteczko 2014 Specjalne komparatory

(c) Krzysztof Barteczko 2014 Porządkowanie - przykład Ta sama lista pracowników – elist. System.out.println("Naturalny porządek wg implementacji Comparable"); Collections.sort(elist); System.out.println(elist); System.out.println("Porządkowanie po pensjach z użyciem komparatora"); Collections.sort(elist, new Comparator () public int compare(Employee e1, Employee e2) { return e1.getSalary() - e2.getSalary(); } }); System.out.println(elist); System.out.println("Odwrócony naturalny porządek"); Collections.sort(elist, Collections.reverseOrder()); System.out.println(elist); System.out.println("Sortowanie polskich napisów"); List polskie = Arrays.asList("z","ę", "ź", "a", "b", "ą"); System.out.println(" -- w porządku Comparable z klasy String"); Collections.sort(polskie); System.out.println(polskie); System.out.println(" -- z użyciem kolatora"); Collections.sort(polskie, Collator.getInstance(new Locale("pl"))); System.out.println(polskie);

(c) Krzysztof Barteczko 2014 Wynik Naturalny porządek wg implementacji Comparable [Adam Kowalski 5700, Jan Kowalski 3500, Jan Kowalski 1400, Jan Malinowski 3500] Porządkowanie po pensjach z użyciem komparatora [Jan Kowalski 1400, Jan Kowalski 3500, Jan Malinowski 3500, Adam Kowalski 5700] Odwrócony naturalny porządek [Jan Malinowski 3500, Jan Kowalski 1400, Jan Kowalski 3500, Adam Kowalski 5700] Sortowanie polskich napisów -- w porządku Comparable z klasy String [a, b, z, ą, ę, ź] -- z użyciem kolatora [a, ą, b, ę, z, ź]

(c) Krzysztof Barteczko 2014 Lambda jako komparator

(c) Krzysztof Barteczko 2014 Wsparcie implementacji w interfejsie Comparator można elastycznie sortować listy.

(c) Krzysztof Barteczko 2014 Przykład – dynamiczny wybór komparatorów public static void main(String[] args) { // nasza tradycyjna lista pracowników List elist = Arrays.asList ( new Employee("Jan", "Kowalski", 3500), new Employee("Jan", "Malinowski", 3500), new Employee("Jan", "Kowalski", 1400), new Employee("Adam", "Kowalski", 5700) ); // opis dwóch porządków "wprost" String mi[] = { "porządek naturalny", "porządek wg pensji" }; // Lista komparatorów Comparator comp; // na tej zmiennej zapiszemy komparator do odwrócenia List > clist = Arrays.asList ( Comparator.naturalOrder(), Comparator.reverseOrder(), comp = (e1, e2) -> e1.getSalary() - e2.getSalary(), comp.reversed() // w odwrotnym porządku pensji ); // Przygotowanie komunikatu do wyświetlenia String menuDescr = "Wybierz porządek:"; for (int i = 0, j = 0; i < mi.length; i++) { menuDescr += "\n" + ++j + " - " + mi[i] + "\n" + ++j + " - odwrócony " + mi[i]; } // Dialogowa częsc aplikacji, umożliwiająca wybory komparatorów int idx = 0; while (true) { try { idx = new Scanner(showInputDialog(menuDescr)).nextInt(); elist.sort((Comparator ) clist.get(idx-1)); showMessageDialog(null, elist); } catch (NullPointerException exc) { break; } catch (Exception exc) { continue; } }

(c) Krzysztof Barteczko 2014 Inne metody interfejsu Comparator

(c) Krzysztof Barteczko 2014 Inne metody interfejsu Comparator - użycie List elist = Arrays.asList ( new Employee("Jan", "Kowalski", 3500), new Employee("Jan", "Malinowski", 3500), new Employee("Jan", "Kowalski", 1400), new Employee("Adam", "Kowalski", 5700), new Employee("Adam", "Abacki", 5700) ); elist.sort(Comparator.comparing(e -> e.getSalary())); System.out.println(elist); elist.sort(Comparator.comparing(Employee::getSalary)); System.out.println(elist); elist.sort(Comparator.comparing(Employee::getFirstName).thenComparing( (e1,e2) -> e1.getSalary() - e2.getSalary())); System.out.println(elist); elist.sort(Comparator.comparing(Employee::getSalary).thenComparing(Employee::getFirstName).thenComparing(Employee::getLastName)); System.out.println(elist); [Jan Kowalski 1400, Jan Kowalski 3500, Jan Malinowski 3500, Adam Kowalski 5700, Adam Abacki 5700] [Adam Kowalski 5700, Adam Abacki 5700, Jan Kowalski 1400, Jan Kowalski 3500, Jan Malinowski 3500] [Jan Kowalski 1400, Jan Kowalski 3500, Jan Malinowski 3500, Adam Abacki 5700, Adam Kowalski 5700]

(c) Krzysztof Barteczko 2014 Zbiory uporządkowane i nawigowalne TreeSet – drzewo czerwono-czarne, by szybko wyszukiwać. Skutek UBOCZNY = uporządkowanie.

(c) Krzysztof Barteczko 2014 Przykład W obu przypadkach straciliśmy pracownika. Gdy porządek był naturalny do zbioru nie trafił Jan Kowalski z pensja 3500, bo miał takie samo imię i nazwisko jak inny pracownik. Gdy ustaliliśmy porządek wg pensji, to został on wyeliminowany, bo miał taka samą pensję jak kto inny.

(c) Krzysztof Barteczko 2014 Dodawanie do zbiorów: jak definiować komparatory? Nasze klasy powinny być przygotowane na to, że ich obiekty mogą znaleźć się w zbiorach typu HashSet albo TreeSet, zatem powinny definiować wszystkie wspomniane metody. I do tego w sposób spójny: używając w nich porównań wobec tych samych pól klasy oraz gwarantując, że jeśli equals zwraca true, to compareTo (lub compare) winno zwracać zero, a hashCode te same wartości dla obu porównywanych obiektów. Dodatkowy argument: nowa realizacja klasy HashSet w Javie 8 opiera sie na specjalnej tablicy asocjacyjnej (mapie), w której wyszukiwanie elementów w kubełkach odbywa się za pomocą drzewa czerwono-czarnego i metody compareTo, o ile liczba elementów w kubełku jest dostatecznie duża, a ich klasa implementuje interfejs Comparable.

(c) Krzysztof Barteczko 2014 Dodatkowe metody Sorted i Navigable - Set Dla zbiorów uporządkowanych (naturalnie lub za pomocą komparatora) dostępna jest możliwośc uzyskiwania “pierwszego” lub “ostatniego” (w zdefiniowanym porządku) elementu, a także podzbiorów, które zawierają elementy “od” - “do” (w zdefiniowanym porządku). Służą temu metody interfejsu SortedSet m.in. headSet(), tailSet() i subSet(), Interfejs NavigableSet bezpośrednio implementowany przez TreeSet dostarcza dodatkowych metod m.in. higher(...), lower(...), ceiling(...), floor(....) które pozwalają uzyskiwac elementy "bliskie" w porządku wobec danego (proszę zobaczyć dokumentację).