Kapitel 12: Java Collections – Teil II ! Übersicht ! Set und TreeSet ! Map und TreeMap ! Arrays und ihre statische Methoden ! Collections und ihre statische Methoden Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-1 In diesem Kapitel Interface Iterable<E> Klasse extends implements Collection<E> List<E> Queue<E> Deque<E> ArrayDeque<E> LinkedList<E> Prof. Dr. O. Bittel, HTWG Konstanz ArrayList<E> Set<E> Map<K,V> SortedSet<E> SortedMap<K,V> NavigableSet<E> NavigableMap<K,V> TreeSet<E> TreeMap<K,V> Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-2 Collection: Set und TreeSet Iterable<E> Collection<E> Interface Klasse extends implements Set<E> SortedSet<E> NavigableSet<E> HashSet<E> TreeSet<E> LinkedHashSet<E> Prof. Dr. O. Bittel, HTWG Konstanz ! Auf den folgenden Folien werden nur das Interface Set mit ihren Erweiterungen SortedSet und NavigableSet und die Implementierung TreeSet besprochen. ! Hashverfahren und die damit zusammenhängenden HashSetImplementierungen werden im nächsten Semester in Algorithmen und Datenstrukturen besprochen. Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-3 Collection<E> public interface Collection<E> extends Iterable<E> { boolean add(E e); boolean addAll(Collection<? extends E> c); // add the element e // add the contents of c boolean remove(Object o); boolean removeAll(Collection<?> c) boolean retainAll(Collection<?> c); void clear(); // remove the element o // remove the elements in c // remove the elements not in c // remove all elements boolean contains(Object o); boolean containsAll(Collection<?> c); boolean isEmpty(); int size(); // true if o is present // true if all elements of c are present // true if no element is present // number of elements Iterator<E> iterator(); Object[ ] toArray(); <T> T[ ] toArray(T[ ] t); // returns an Iterator over the elements // copy contents to an Object[ ] // copy contents to a T[ ] for any T } Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-4 Set<E> Collection<E> Set<E> ! Das Interface Set hat gegenüber Collection keine neue Methoden. ! Jedoch ist die Vetragsbedingung von add und addAll verschärft. ! add(x) von Collection garantiert lediglich, dass sich x nach Aufruf von add(x) im Container befindet. Es wird keine Aussage für den Fall getroffen, dass sich das Element bereits im Container befindet. ! add(x) von Set fügt x nur dann zum Container dazu, falls x noch nicht im Container enthalten ist. ! addAll wird analog verschärft. Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-5 SortedSet<E> Set<E> SortedSet<E> ! SortedSet ist eine Menge, deren Elemente sortiert sind. ! Die Elemente sind entweder über compareTo (natürliche Ordnung) oder mit einem Comparator-Objekt sortiert, das typischerweise beim Konstruktoraufruf (siehe TreeSet) übergeben wird. public interface SortedSet<E> extends Set<E> { Comparator<? super E> comparator(); SortedSet<E> subSet(E fromElementInclusive, E toElementExclusive); SortedSet<E> headSet(E toElementExclusive ); SortedSet<E> tailSet(E fromElementInclusive); E first(); E last(); } // returns a range view. // returns a range view. // returns a range view. ! comparator liefert das Vergleichsobjekt zurück, nach dem geordnet wird. ! subSet, headSet und tailSet liefern entsprechende Teilmengen als Sichten (views) zurück. Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-6 NavigableSet<E> SortedSet<E> NavigableSet<E> ! Gegenüber SortedSet gibt es Navigationsmethoden, die zu einem Element das nächst kleinere bzw. nächst größere Element zurückliefern. ! Statt "kleiner" bzw. "größer" geht auch "kleiner gleich" bzw. "größer gleich". ! Es gibt einen rückwärtslaufenden Iterator. public interface NavigableSet<E> extends SortedSet<E> { } E lower(E e); // greatest element less than e, or null if there is no such element E higher(E e); // least element greater than e, or null if there is no such element E floor(E e); // greatest element less than or equal to e, or null if there is no such element E ceiling(E e); // least element greater than or equal to e, or null if there is no such element E pollFirst(); E pollLast(); NavigableSet<E> descendingSet(); // returns a reverse-order view. Iterator<E> descendingIterator(); // returns a reverse-order iterator. NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive); NavigableSet<E> headSet(E toElement, boolean inclusive); NavigableSet<E> tailSet(E fromElement, boolean inclusive); Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-7 TreeSet<E> NavigableSet<E> TreeSet<E> ! TreeSet ist eine Implementierung als balanzierter Binärbaum (genauer: Rot-Schwarz-Baum; siehe Algorithmen und Datenstrukturen im nächsten Semester). ! Die wichtigen Methoden wie add, remove und contains benötigen daher nur eine Laufzeit von O(log n). ! Der parameterlose Konstruktor setzt eine compareToMethode für die Elemente voraus. (Elemente müssen vom Typ Comparable sein.) ! Aus Flexibilitätsgründen gibt es auch einen Konstruktor, dem ein Vergleichsobjekt für die Festlegung der Reihenfolge der Elemente übergeben wird. public class TreeSet<E> implements NavigableSet<E> { public public public public TreeSet() {...} TreeSet(Comparator<? super E> comparator) {...} TreeSet(Collection<? extends E> c) {...} TreeSet(SortedSet<E> s) {...} } Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-8 Anwendungsbeispiel mit TreeSet<E> ! Indexerstellung für eine Datei: alle Wörter, die in einer Datei vorkommen, werden alphabetisch ausgegeben. public class Demo { public static void main(String[] args) throws FileNotFoundException { Scanner in = new Scanner(new File("input.txt")); // Wortmenge definieren: SortedSet<String> words = new TreeSet<>(); // Alle Woerter aus Datei einlesen und in Menge einfuegen: while (in.hasNext()) words.add(in.next()); // Wortmenge alphabetisch ausgeben: for (String w : words) System.out.println(w); } } Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-9 Kapitel 12: Java Collections – Teil II ! Übersicht ! Set und TreeSet ! Map und TreeMap ! Arrays und ihre statische Methoden ! Collections und ihre statische Methoden Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-10 Map ! Maps sind Mengen von Schlüssel-Wert-Paaren, wobei ein Schlüssel nicht mehrfach vorkommen darf. ! Beispiel Telefonbuch: − Schlüssel = Familienname − Wert = Telefonummer (Es sei angenommen, dass der Familienename eindeutig ist, ansonsten Vorname und Adresse dazunehmen) ! Beispiel Deutsch-Englisch-Wörterbuch: − Schlüssel = deutsches Wort − Wert = Menge von englischen Wörtern. ! Eine Map bildet einen Schlüssel auf den entsprechenden Wert ab. Daher auch der Name: Map = Abbildung. Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-11 Collection Map<K,V> ! Map<K,V> ist ein generischer Typ. K steht für Key und ist der Schlüsseltyp. V steht für Value und ist der Werttyp. public interface Map<K, V> { V put(K key, V value); void putAll(Map<? extends K, ? extends V> m); // add or replace a key-value-pair // add all key-value-pairs of m void clear(); V remove(Object key) ; // remove all key-value-pairs // remove key-value-pair V get(Object key); boolean containsKey (Object key); boolean containsValue (Object value); boolean isEmpty(); int size(); // return the value corresponding to key // return true if key is present in the map // return true if value is present in the map // true if no key-value-pair is present // number of key-value-pairs Set< Map.Entry<K, V> > entrySet(); Set<K> keySet(); Collection<V> values(); // return a Set view of the key-value-pairs // return a Set view of the keys // return a Collection view of the values } ! Map.Entry<K,V> ist der Typ für die Schlüssel-Wert-Paare. Es gibt u.a. die Methoden getKey(), getValue() und setValue(V value). ! Es gibt für Maps keine Iteratoren! Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-12 Map<K,V> und ihre Implementierungen Map<K,V> Interface Klasse SortedMap<K,V> NavigableMap<K,V> TreeMap<K,V> EnumMap<K,V> WeakHashMap<K,V> IndentityHashMap<K,V> HashMap<K,V> extends implements ! SortedMap, NavigableMap und TreeMap sind analog zu SortedSet, NavigableSort und TreeSet aufgebaut. Die Elemente sind nach Ihrem Schlüssel sortiert. ! TreeMap bietet wie erwartet einen Konstruktor an, dem ein Vergleichsobjekt für die Festlegung der Reihenfolge der Schlüssel übergeben werden kann. ! Hashverfahren und die damit zusammenhängenden HashMapImplementierungen werden im nächsten Semester in Algorithmen und Datenstrukturen besprochen. LinkedHashMap<K,V> Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-13 Anwendung: Telefonbuch als TreeMap (1) public class TelBuchAnwendung{ public static void main(String[] args) { Telefonbuch definieren. NavigableMap<String,Integer> telBuch = new TreeMap<>(); // Kunden eintragen: telBuch.put("Maier", 1234); telBuch.put("Anton", 4567); telBuch.put("Meyer", 4711); telBuch.put("Mueller", 7890); telBuch.put("Vogel", 1357); telBuch.put("Baier", 2468); Teilnehmer eintragen. // TelNummer nachschlagen: Telefonnummer nachschlagen. Integer telNr; if ((telNr = telBuch.get("Vogel")) != null) { System.out.println("Vogel: " + telNr); } // TelNummer aendern: telBuch.put("Maier", 4321); Telefonnummer ändern. ... Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-14 Anwendung: Telefonbuch als TreeMap (2) Anton: 4567 Baier: 2468 Maier: 4321 Meyer: 4711 Mueller: 7890 Vogel: 1357 ... } // TelBuch sortiert ausgeben: for (Map.Entry<String,Integer> eintrag : telBuch.entrySet()) { System.out.println(eintrag.getKey() + ": " + eintrag.getValue()); } Anton // Nur Kundennamen des TelBuchs ausgeben: Baier for (String kunde : telBuch.keySet()) { Maier System.out.println(kunde); Meyer } Mueller Vogel // Bereichssichten: TelBuch nur mit 'M' ausgeben: System.out.println("Telefonbucheintaege mit M:"); for (Map.Entry<String,Integer> eintrag : telBuch.subMap("M", true, "N", false).entrySet()) { System.out.println(eintrag.getKey() + ": " + eintrag.getValue()); } Maier: 4321 Meyer: 4711 Mueller: 7890 Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-15 Aufgabe - Indexerstellung ! Schreiben Sie ein Programm, das für eine Eingabedatei (z.B. input.txt) einen Index erstellt und ausgibt. ! Ein Index ist eine alphabetisch sortierte Folge der im Text vorkommenden Wörter. Für jedes Wort werden außerdem die Nummern der Zeilen angegeben, in denen das Wort vorkommt. ! Verwenden Sie geeignete Container aus der Java-API. 1 2 3 4 5 input.txt Index das Haus ist hoeher als das andere Haus Haus: als: andere: das: hoeher: ist: 1, 5 3 4 1, 4 2 2 ZeilenNummern Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-16 Kapitel 12: Java Collections – Teil II ! Übersicht ! Set und TreeSet ! Map und TreeMap ! Arrays und ihre statische Methoden ! Collections und ihre statische Methoden Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-17 Suchen und Sortieren mit java.util.Arrays (1) ! Die Klasse Arrays besteht ausschließlich aus statischen Methoden zum Bearbeiten von Feldern. ! Es gibt u.a. Methoden zum Suchen und Sortieren. Dabei kann auch nur ein Teil des Feldes [fromIndex, toIndex) durchsucht bzw. sortiert werden. ! Es gibt Methoden für Felder mit Basisdatentypen, für Object-Felder und für generische Felder. ! binarySearch für Basisdatentypen führt eine binäre Suche durch und setzt daher voraus, dass das Feld bereits sortiert ist. public static int binarySearch(int[ ] a, int key); public static int binarySearch(double[ ] a, double key); public static int binarySearch(int[ ] a, int fromIndex, int toIndex, int key); public static int binarySearch(double[ ] a, int fromIndex, int toIndex, double key); ... Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-18 Suchen und Sortieren mit java.util.Arrays (2) ! sort für Basisdatentypen ist ein modifiziertes QuickSort mit 2 Pivotelementen (Dual-Pivot Quicksort) und einer Partitionierung in 3 Teilen. ! Das Sortierverfahren ist nicht stabil. public static void sort(int[ ] a); public static void sort(int[ ] a, int fromIndex, int toIndex); public static void sort(double[ ] a); public static void sort(double[ ] a, int fromIndex, int toIndex); ... ! sort für ein Object-Feld ist eine modifizierte MergeSort-Variante. ! Die Elemente müssen vom Typ Comparable sein. ! Das Sortierverfahren ist stabil. public static void sort(Object[ ] a); public static void sort(Object[ ] a, int fromIndex, int toIndex); Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-19 Suchen und Sortieren mit java.util.Arrays (3) ! binarySearch und sort gibt es auch als generische Methoden. ! sort ist eine modifizierte MergeSort-Variante und ist daher stabil (wie das sort für Object-Felder). ! Die Vergleichsoperation wird dabei als Comparator-Objekt verpackt und als Parameter übergeben. static <T> int binarySearch(T[ ] a, T key, Comparator<? super T> c); static <T> int binarySearch(T[ ] a, int fromIndex, int toIndex, T key, Comparator<? super T> c); static <T> void sort(T[ ] a, Comparator<? super T> c); static <T> void sort(T[ ] a, int fromIndex, int toIndex, Comparator<? super T> c); ! Die Vergleichsoperation c muss wenigstens Elemente vom Typ T vergleichen können. Daher: Comparator<? super T>. ! Es darf c == null sein. Dann wird die Standard-Ordnung verwendet. Dazu muss aber T Subtyp von Comparable<? super T> sein. Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-20 Kapitel 12: Java Collections – Teil II ! Übersicht ! Set und TreeSet ! Map und TreeMap ! Arrays und ihre statische Methoden ! Collections und ihre statische Methoden Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-21 Klasse java.util.Collections (1) ! Die Klasse Collections besteht ausschließlich aus statischen, generischen Methoden, die auf Collections arbeiten bzw. Collections zurückliefern. ! Methoden zum Ändern der Reihenfolge von Elementen: reverse, rotate, shuffle, sort, swap ! Methoden zum Ändern der Inhalte eines Containers: copy, fill, replaceAll ! Methoden zum Suchen von Elementen: min, max, binarySearch, ... Sortiermethoden: public static <T extends Comparable<? super T>> void sort(List<T> list); public static <T> void sort(List<T> list, Comparator<? super T> c) ! Die Sortierverfahren sind eine mergeSort-Variante und sind damit stabil. Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-22 Klasse java.util.Collections (2) Suchmethoden: public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key); public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c); ! binarySearch führt eine binäre Suche durch und setzt daher voraus, dass die Liste bereits sortiert ist. ! Nur bei einer ArrayList wird eine O(log n)-Laufzeit garantiert. ! Bei einer LinkedList kommt das Verfahren zwar mit O(log n) Vergleichen aus, benötigt aber aufgrund der Traversierung durch die linear verkettete Liste O(n)-Laufzeit. Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik II – Java Collections - Teil 2 WS 16/17 12-23