Softwaretechnik 1 Vorlesung 2.4. Java Collections Framework Prof. Dr. Bernhard Rumpe Software Systems Engineering Technische Universität Braunschweig http://www.sse.cs.tu-bs.de/ Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java Klassenbibliothek 2 Java: Objektorientierte Sprache mit bekannten Konzepten (Klassen, Interfaces, Packages, Sichtbarkeiten, Vererbung, ...) zusätzlich: umfangreiche Klassenbibliothek aus der Standardfunktionalität importiert werden kann Java 2 Standard Edition 5.0 Klassenbibliothek: • 3279 Klassen und Interfaces in 166 Packages Ziel: Wiederverwendung • schnellere Entwicklung • weniger Fehler • performantere Implementierung Problem: • Kennen der vorhandenen Funktionalität • Entscheidung zwischen Alternativen wichtiges Hilfsmittel: Java API Dokumentation API = Application Programming Interface http://java.sun.com/j2se/1.5.0/docs/api/ Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java API Dokumentation 3 Java Klassenbibliothek - Beispiele 4 java.lang • einfache Datentypen: Integer, Boolean, Double, ... • Zugriff auf Umgebungsvariablen, Standard-Streams • nebenläufige Programmierung, Threads java.io • Ein- / Ausgabe: Kapselung in Streams, Zugriff mittels Reader und Writer java.net • Netzwerkprogrammierung: URLs, Sockets, Protokolle, ... java.awt, javax.swing • GUI-Programmierung: Fenster, Dialoge, Buttons, ... java.util • Hilfsklassen für Kalender- und Datumsfunktionalität, Zufallszahlen, ... • Java Collections Framework Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java Collections Framework 5 Collection • Objekt, das eine Gruppe von Objekten repräsentiert • • • • zur Strukturierung der Daten entscheiden häufig über Effizienz der Operationen, Anwendung vgl. Datenstrukturen aus AuD I,II und Prog I,II bekannte Datenstrukturen ? • Operationen zur Abfrage, Manipulation • contains(..), size(), add(..), ... Framework • Definition (nach Pomberger/Blaschek): Ein "framework" (Rahmenwerk, Anwendungsgerüst) ist eine Menge von zusammengehörigen Klassen, die einen abstrakten Entwurf für eine Problemfamilie darstellen. Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java Collections Framework 6 Vorteile • reduzierter Programmieraufwand • Anpassbarkeit und Optimierbarkeit • erhöhte Performance • weniger Fehler • Interoperabilität von unabhängigen APIs • erhöhte Wiederverwendbarkeit • erhöhte Verständlichkeit „Nachteil“ • erhöhter Einarbeitunsaufwand durch „erstes Lernen“ Umfang: ca. 45 Klassen und Interfaces im Package java.util Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java Collections Framework 7 Übersicht über die wichtigsten Interfaces und Implementierungen Vererbung (extends) Implementierung (implements) <<interface>> Collection <<interface>> Set <<interface>> List SortedSet Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Map <<interface>> SortedMap BlockingQeue ArrayList TreeSet <<interface>> Queue <<interface>> <<interface>> HashSet <<interface>> LinkedList HashMap PriorityQueue ArrayBlockingQueue TreeMap Java Collections Framework 8 Übersicht über die wichtigsten Interfaces und Implementierungen Vererbung (extends) Implementierung (implements) <<interface>> Collection <<interface>> Set <<interface>> List SortedSet TreeSet Queue <<interface>> Map <<interface>> <<interface>> HashSet <<interface>> <<interface>> SortedMap BlockingQeue ArrayList LinkedList PriorityQueue HashMap ArrayBlockingQueue TreeMap Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Interface Collection 9 „kleinster gemeinsamer Nenner“ der Collection Implementierungen schreibt Operationen für den Zugriff und die Manipulation der unterliegenden Daten vor Besonderheiten: • optionale Operationen sind in der API Dokumentation als optional markiert und müssen nicht implementiert werden • lösen zur Laufzeit UnsupportedOperationException aus • aber: alle konkreten Implementierungen in java.util implementieren alle optionalen Methoden • Map ist Teil des Collections Framework, leitet aber nicht von Collection ab Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Interface Collection 10 verbindliche Operationen • boolean contains(Object o) • liefert true, wenn die Collection o enthält • boolean containsAll(Collection c) • liefert true, wenn die Collection alle Elemente von c enthält • boolean isEmpty() • liefert true, wenn die Collection keine Elemente enthält • Iterator iterator() • liefert einen Iterator über alle Elemente • int size() • liefert die Anzahl der Elemente • Object[] toArray() • liefert ein Array, das die Elemente enthält • Object[] toArray(Object[] a) • wie oben, der Laufzeittyp des Array ist der von a Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Interface Collection 11 optionale Operationen • boolean add(Object o) • fügt o zur Collection hinzu • boolean addAll(Collection c) • fügt alle Elemente von c zur Collection hinzu • void clear() • leert die Collection • boolean remove(Object o) • entfernt o aus der Collection • boolean removeAll(Collection c) • entfernt alle Elemente von c aus der Collection • boolean retainAll(Collection c) • entfernt alle Elemente der Collection, die nicht in c sind Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Iteratoren 12 jede Collection besitzt die Methode • Iterator iterator() Iteration über die Elemente der Collection Interface Iterator • verbindliche Operationen • boolean hasNext() • true, falls Collection weitere Elemente enthält • Object next() • liefert das nächste Element der Collection • optionale Operationen • void remove() • löscht das letzte mit next() zurückgelieferte Element aus der Collection Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Beispiel 13 import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class CollectionBsp1 { public static void main(String[] args) { Collection c = new ArrayList(); for (int i = 0; i < 10; i++) { c.add(i); } Iterator iterator = c.iterator(); while( iterator.hasNext() ) { System.out.print( iterator.next() + " " ); } } } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Beispiel - Anpassbarkeit 14 import java.util.HashSet; import java.util.Collection; import java.util.Iterator; public class CollectionBsp1 { public static void main(String[] args) { Collection c = new HashSet(); for (int i = 0; i < 10; i++) { c.add(i); } Iterator iterator = c.iterator(); while( iterator.hasNext() ) { System.out.print( iterator.next() + " " ); } } } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Listen 15 Vererbung (extends) Implementierung (implements) <<interface>> Collection <<interface>> <<interface>> List Set SortedSet Seite <<interface>> Map <<interface>> SortedMap BlockingQeue ArrayList TreeSet Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Queue <<interface>> <<interface>> HashSet <<interface>> LinkedList PriorityQueue HashMap ArrayBlockingQueue TreeMap Listen 16 Liste oder Sequenz von Objekten, geordnet doppelte Elemente erlaubt Einfügen von null erlaubt zusätzliche verbindliche und optionale Operationen bieten speziellen ListIterator mit erweiterter Funktionalität Implementierungen • ArrayList • • • • Listenimplementierung auf Array Basis benötigte Arraygröße wird dynamisch angepaßt anfängliche Größe des Arrays kann angegeben werden optimale Arraygröße kann erzwungen werden • LinkedList • Listenimplementierung als doppelt verkettete Liste • zusätzliche Operationen zum Einfügen/Entfernen/Zugriff auf Anfang und Ende der Liste Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Listen 17 zusätzliche verbindliche Operationen • Object get(int i) • liefert das i-te Element der Liste • int indexOf(Object o) • liefert die Position des ersten Auftretens von o in der Liste • int lastIndexOf(Object o) • liefert die Position des letzten Auftretens von o in der Liste • ListIterator listIterator() • liefert den erweiterten Iterator für Listen • ListIterator listIterator(int index) • liefert den Iterator ab dem angegeben Index • List subList(int fromIndex, int toIndex) • liefert eine Teilliste von Position fromIndex (inkl.) bis Position toIndex (exkl.) Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Listen 18 zusätzliche optionale Operationen • void add(int index, Object element) • fügt element an Position index ein • boolean addAll(int index, Collection c) • fügt alle Elemente von c in die Liste ein beginnend ab index • Object remove(int i) • entfernt das i-te Element der Liste • Object set(int i, Object element) • ersetzt das i-te Element der Liste durch element Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Listen und ListIterator 19 zusätzliche Operation zu herkömmlichen Iterator verbindliche Operationen • boolean hasPrevious() • true, falls es noch vorhergehende Elemente existieren • Object previous() • liefert das vorhergehende Element • int nextIndex() • liefert den Index des nächsten mit next() gelieferten Elements • int previousIndex() • liefert den Index des nächsten mit previous() gelieferten Elements optionale Operationen • void add(Object o) • fügt o in die Liste vor die aktuelle Iteratorposition ein • void set(Object o) • ersetzt das letzte durch next() oder previous() gelieferte Element durch o Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Listen - Beispiel 20 dozent Veranstaltung titel : String sws : int schein : boolean zeit : Calendar * 1 Dozent name : String email : String buero : int Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Listen - Beispiel 21 public List init() { Dozent meier = new Dozent("Meier","[email protected]",123); ... Calendar vl1Zeit = java.util.Calendar.getInstance(); vl1Zeit.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY); vl1Zeit.set(Calendar.HOUR_OF_DAY, 9); vl1Zeit.set(Calendar.MINUTE,45); Veranstaltung vl1 = new Veranstaltung("Software Systems",3, false,meier,vl1Zeit); ... Veranstaltung vl2 = new Veranstaltung("Software Testen", 5, true, mueller, vl2Zeit); ... Veranstaltung vl3 = new Veranstaltung("Software Architektur", 4, true, schulz, vl3Zeit); ... Veranstaltung vl4 = new Veranstaltung("Psychologie", 4, true, schmidt, vl4Zeit); List veranstaltungen = new ArrayList(10); veranstaltungen.add(vl1); veranstaltungen.add(vl2); veranstaltungen.add(vl3); veranstaltungen.add(vl4); return veranstaltungen; } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Listen - Beispiel 22 public void print() { List veranstaltungen = init(); ListIterator listIt = veranstaltungen.listIterator(); while( listIt.hasNext() ) { System.out.println(listIt.nextIndex() + ": " + ((Veranstaltung)listIt.next()).getTitel()); } // 0: Software Systems // 1: Software Testen // 2: Software Architektur // 3: Psychologie while( listIt.hasPrevious() ) { System.out.println(listIt.previousIndex() + ": " + ((Veranstaltung)listIt.previous()).getTitel()); } // 3: Psychologie // 2: Software Architektur // 1: Software Testen // 0: Software Systems } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Listen Implementierungen 23 ArrayList und LinkedList sind konkrete Listenimplementierungen Wann ist welche Liste sinnvoll? Performancevergleich • LinkedList • schnelles Einfügen und Löschen in O(1) bzw. O(n) • wahlfreier Zugriff in O(n) • ArrayList • wahlfreier Zugriff in O(1) • Einfügen und Löschen u.U. teuer, reicht die Kapazität des Array nicht aus, muss die gesamte Liste in ein neues Array umkopiert werden evtl. eigene Performancemessung Daumenregel: • Bei häufigem Zugriff und seltenen Änderungsoperationen: ArrayList • Bei häufigen Änderungen und seltenem wahlfreien Zugriff: LinkedList Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Mengen 24 Vererbung (extends) Implementierung (implements) <<interface>> Collection <<interface>> Set <<interface>> List SortedSet TreeSet Queue <<interface>> Map <<interface>> <<interface>> HashSet <<interface>> <<interface>> SortedMap BlockingQeue ArrayList LinkedList PriorityQueue HashMap ArrayBlockingQueue TreeMap Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Mengen 25 keine Duplikate keine Reihenfolge der Elemente mittels SortedSet kann natürliche Ordnung der Elemente hergestellt werden Mengenoperationen wie Vereinigung, Schnitt durch Standard Collection Operationen addAll(), retainAll() Implementierungen • HashSet • keine garantierte Ordnung der Elemente bei Iteration • basiert auf HashMap • daher O(1) Performance für Basisoperationen (add, contains and remove) • LinkedHashSet • leitet von HashSet ab, garantiert aber die Reihenfolge der Elemente (Einfügereihenfolge) • TreeSet • aufsteigende natürliche Ordnung der Elemente • basiert auf TreeMap • O(log(n)) für Basisoperationen (add, remove and contains) Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Interface SortedSet 26 verbindliche Operationen • Comparator comparator() • liefert den Comparator, der mit dem Set assoziiert ist • Object first() • lieferte das „kleinste“ Element der Menge • SortedSet headSet(Object toElement) • liefert die Teilmenge mit Elementen „echt kleiner“ als toElement • Object last() • liefert das „größte“ Element der Menge • SortedSet subSet(Object fromElement, Object toElement) • liefert die Teilmenge mit Elementen „größer gleich“ fromElement und „echt kleiner“ als toElement • SortedSet tailSet(Object fromElement) • liefert die Teilmenge mit Elementen „größer gleich“ fromElement Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Mengen Beispiel 27 dozent Veranstaltung titel : String sws : int schein : boolean zeit : Calendar * 1 Dozent name : String email : String buero : int add(Teilnehmer t) * * Teilnehmer name : String matrikel : int Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Mengen Beispiel 28 public class Veranstaltung { Set teilnehmer; public Veranstaltung(String titel, int sws, boolean schein, Dozent dozent, Calendar zeit) { ... this.teilnehmer = new HashSet(); } public void addTeilnehmer(Teilnehmer t) { teilnehmer.add(t); } public Set getTeilnehmer() { return teilnehmer; } ... } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Mengen Beispiel 29 Veranstaltung vl1 = new Veranstaltung(..); Veranstaltung vl2 = new Veranstaltung(..); Teilnehmer Teilnehmer Teilnehmer Teilnehmer pete = new Teilnehmer("Pete", 1); jon = new Teilnehmer("Jon", 2); marc = new Teilnehmer("Marc", 3); sam = new Teilnehmer("Sam", 4); vl1.addTeilnehmer(pete); vl1.addTeilnehmer(jon); vl1.addTeilnehmer(marc); vl2.addTeilnehmer(pete); vl2.addTeilnehmer(marc); Set vl1Teilnehmer = vl1.getTeilnehmer(); Set vl2Teilnehmer = vl2.getTeilnehmer(); Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Mengen Beispiel 30 //vl1Teilnehmer = {Pete ,Jon ,Marc} //vl2Teilnehmer = {Pete, Sam} //Vereinigung bilden : Teilnehmer von vl1 oder vl2 Set union = vl1Teilnehmer; // Achtung: keine Kopie! union.addAll(vl2Teilnehmer); Iterator iter = union.iterator(); while(iter.hasNext()) { System.out.println(iter.next()); // union = {Pete, Jon, Marc, Sam} } //Schnitt bilden : Teilnehmer von vl1 und vl2 Set intersection = vl1Teilnehmer; intersection.retainAll(vl2Teilnehmer); Iterator iter = intersection.iterator(); while(iter.hasNext()) { System.out.println(iter.next()); // intersection = {Pete} } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Schlangen 31 Vererbung (extends) Implementierung (implements) <<interface>> Collection <<interface>> Set <<interface>> List SortedSet Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite <<interface>> Map <<interface>> SortedMap BlockingQeue ArrayList TreeSet Queue <<interface>> <<interface>> HashSet <<interface>> LinkedList PriorityQueue HashMap ArrayBlockingQueue TreeMap Schlangen 32 Elemente geordnet Zugriff normalerweise nach dem FIFO (first in, first out) Prinzip Varianten: • BlockingQueue (eigenes Interface): blockierender Zugriff bei leerer oder voller Schlange • PriorityQueue: Element mit höchster Priorität wird zuerst zugegriffen Implementierung • viele Subklassen, speziell für nebenläufige Programmierung (java.util.concurrent) • PriorityBlockingQueue • ArrayBlockingQueue Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Schlangen – Interface Queue 33 zusätzliche verbindliche Operationen • Object element() • liefert erstes Element der Schlange, entfernt es aber nicht, löst NoSuchElementException aus, falls Schlange leer • boolean offer(Object o) • liefert true, falls o in die Schlange eingefügt werden konnte • Object peek() • liefert erstes Element der Schlange, entfernt es aber nicht, liefert null, falls Schlange leer • Object poll() • liefert erstes Element der Schlange und entfernt es, liefert null, falls Schlange leer • Object remove() • liefert erstes Element der Schlange und entfernt es, löst NoSuchElementException aus, falls Schlange leer Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Schlangen – Interface BlockingQueue 34 zusätzliche optionale Operationen • boolean add(Object o) • fügt o sofort ein, löst IllegalStateException aus, falls nicht möglich • int drainTo(Collection c) • entfernt alle Elemente der Qeue und fügt sie in c ein • int drainTo(Collection c, int maxElements) • entfernt maximal maxElements und fügt sie in c ein • boolean offer(Object o, long timeout, TimeUnit unit) • fügt o ein, wartet maximal timeout Zeiteineinheiten (unit), falls nicht sofort möglich • Object poll(long timeout, TimeUnit unit) • entfernt das erste Element der Schlange, wartet timeout Zeiteinheiten (unit), falls nicht sofort möglich • void put(Object o) • fügt o ein, wartet, falls nicht sofort möglich • int remainingCapacity() • liefert die Anzahl der noch einfügbaren Elemente, bevor die Schlange blockiert • Object take() • entfernt das erste Element der Schlange, wartet, falls nicht sofort möglich Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Schlangen Beispiel 35 dozent Veranstaltung titel : String sws : int schein : boolean zeit : Calendar BlockingQueue : prueflinge add(Teilnehmer t) pruefung() * 1 Dozent name : String email : String buero : int 1 * Teilnehmer name : String matrikel : int Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Schlangen Beispiel 36 class Veranstaltung { ... BlockingQueue prueflinge = new ArrayBlockingQueue(2); public void pruefung() { DozentThread doz = new DozentThread(dozent, this); doz.start(); System.out.println("Pruefungen fuer die VL " + titel + " von " + dozent.getNachName()); Iterator it = teilnehmer.iterator(); while(it.hasNext()) { Teilnehmer t = (Teilnehmer)it.next(); TeilnehmerThread p = new TeilnehmerThread(t ,this); p.run(); } } } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Schlangen Beispiel 37 public class DozentThread extends Thread { protected Veranstaltung veranstaltung; protected Dozent dozent; public void run() { BlockingQueue pruefling = veranstaltung.getPrueflinge(); int maxPruefungen = veranstaltung.getTeilnehmer().size(); int abgeschlPruefungen = 0; while (abgeschlPruefungen < maxPruefungen) { try { Teilnehmer p = (Teilnehmer)pruefling.poll(1000,TimeUnit.MILLISECONDS); if (p == null) { System.out.println(dozent + " forscht."); } else { System.out.println(dozent + " prueft " + p + "."); abgeschlPruefungen++; } } catch (InterruptedException e) {} }} ... } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Schlangen Beispiel 38 public class TeilnehmerThread extends Thread { private Teilnehmer teilnehmer; private Veranstaltung veranstaltung; public void run() { long zoegern = (long)(new Random()).nextInt(3000); try { Thread.sleep(zoegern); System.out.println(teilnehmer + " meldet sich an."); BlockingQueue warteSchlange = veranstaltung.getPrueflinge(); if (warteSchlange.remainingCapacity() == 0) { System.out.println( teilnehmer.getName() + " muss warten."); } warteSchlange.put(teilnehmer); System.out.println(teilnehmer.getName() + " ist angemeldet."); } catch (InterruptedException e){ } } } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Schlangen Beispiel 39 Beispiel: Pruefungen fuer die VL Software Systems von Meier Meier forscht. Jon ist angemeldet. Pete ist angemeldet. Marc muss warten. Meier prueft Jon. Marc ist angemeldet. Sam muss warten. Meier prueft Pete. Sam ist angemeldet. Meier prueft Marc. Meier prueft Sam. Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Schlange leer, Meier kann forschen Schlange voll, Marc muss warten Wieder Kapazitäten vorhanden Jetzt kann sich Marc anmelden Schlange voll, Sam muss warten Wieder Kapazitäten vorhanden Jetzt kann sich Sam anmelden Assoziative Speicher (Maps) 40 Vererbung (extends) Implementierung (implements) <<interface>> Collection <<interface>> Set <<interface>> List SortedSet TreeSet Queue <<interface>> Map <<interface>> <<interface>> HashSet <<interface>> <<interface>> SortedMap BlockingQeue ArrayList LinkedList PriorityQueue HashMap ArrayBlockingQueue TreeMap Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Assoziative Speicher 41 speichert Key,Value-Paare keine doppelten Schlüssel erlaubt implementiert nicht Collection, weil z.B. add(Object) keinen Sinn ergibt bietet Collection „Sichten“, z.B. durch Collection der Key oder Values Implementierungen • HashMap • keine garantierte Ordnung der Schlüssel bei Iteration • O(1) Performance für Basisoperationen (containsKey, get, put, remove) • LinkedHashMap • leitet von HashMap ab, garantiert aber die Reihenfolge der Schlüssel (Einfügereihenfolge) • TreeMap • aufsteigende natürliche Ordnung der Elemente • O(log(n)) für Basisoperationen (containsKey, get, put, remove) Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Interface Map 42 verbindliche Operationen • boolean containsKey(Object key) • liefert true, falls Eintrag mit Schlüssel key enthalten ist • boolean containsValue(Object value) • liefert true, falls zu value ein oder mehr Einträge vorhanden sind • Set entrySet() • liefert eine Set-Sicht auf die Einträge, Elemente sind vom Typ Map.Entry • Object get(Object key) • liefert den Wert zum Schlüssel key, liefert null falls Mapping nicht existiert oder null der Wert ist • boolean isEmpty() • liefert true, falls keine Schlüssel-Wert-Paare gespeichert sind • Set keySet() • liefert eine Set-Sicht auf die Schlüssel • int size() • liefert die Anzahl der Schlüssel-Wert-Paare • Collection values() • liefert eine Collection-Sicht auf die Werte Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Interface Map 43 optionale Operationen • void clear() • entfernt alle Schlüssel-Wert-Paare • Object put(Object key, Object value) • legt neuen Eintrag mit Schlüssel key und Wert value an, ersetzt ggfs. vorhandene Einträge • void putAll(Map t) • fügt alle Einträge aus t ein • Object remove(Object key) • entfernt den Eintrag mit Schlüssel key und liefert entsprechenden Wert zurück Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Interface SortedMap 44 verbindliche Operationen • Comparator comparator() • liefert den Comparator, der mit dem Map assoziiert ist • Object firstKey() • liefert den „kleinsten“ Schlüssel • SortedMap headMap(Object toKey) • liefert ein Teilmapping mit Schlüsseleinträgen „echt kleiner“ als toKey • Object lastKey() • liefert den „größten“ Schlüssel • SortedMap subMap(Object fromKey, Object toKey) • liefert ein Teilmapping mit Schlüsseleinträgen von fromKey (inkl.) bis toKey (exkl.) • SortedMap tailMap(Object fromKey) • liefert ein Teilmapping mit Schlüsseleinträgen „größer gleich“ fromKey Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Map Beispiel 45 Telefonbuch • zu gegebenem Dozenten (Schlüssel) wird Telefonnummer (Wert) gesucht public class CollectionBsp4 { public void doIt() { Map telefonBuch = new HashMap(); Dozent Dozent Dozent Dozent schmidt = new Dozent("Schmidt"); meier = new Dozent("Meier"); mueller = new Dozent("Müller"); schulz = new Dozent("Schulz"); telefonBuch.put(schmidt,1234); telefonBuch.put(meier,5678); telefonBuch.put(mueller,2345); telefonBuch.put(schulz,6789); System.out.println(telefonBuch.containsKey(schmidt)); // true System.out.println(telefonBuch.get(schmidt)); // 1234 } } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Map Beispiel 46 Problem, falls nicht mit identischem Schlüssel nach dem Wert gefragt wird public class CollectionBsp4 { public void doIt(){ Map telefonBuch = new HashMap(); Dozent Dozent Dozent Dozent schmidt = new Dozent("Schmidt"); meier = new Dozent("Meier"); mueller = new Dozent("Müller"); schulz = new Dozent("Schulz"); telefonBuch.put(schmidt,1234); telefonBuch.put(meier,5678); telefonBuch.put(mueller,2345); telefonBuch.put(schulz,6789); Dozent schmidt2 = new Dozent("Schmidt"); System.out.println(telefonBuch.containsKey(schmidt2)); // false System.out.println(telefonBuch.get(schmidt2)); // null } } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Map Beispiel 47 Lösung: Überschreiben von hashCode() und equals() public class Dozent { ... String nachName; ... //@Override public int hashCode() { return nachName.hashCode(); } //@Override public boolean equals(Object obj) { if (obj instanceof Dozent) { return ((Dozent)obj).getNachName().equals(nachName); } return false; } } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Map Beispiel 48 Aufgabe: Ausgabe des Telefonbuchs (z.B. für den Druck) public class CollectionBsp4 { public void doIt(){ Map telefonBuch = new HashMap(); Dozent Dozent Dozent Dozent schmidt = new Dozent("Schmidt"); meier = new Dozent("Meier"); mueller = new Dozent("Müller"); schulz = new Dozent("Schulz"); telefonBuch.put(schmidt,1234); telefonBuch.put(meier,5678); telefonBuch.put(mueller,2345); telefonBuch.put(schulz,6789); Iterator iter = telefonBuch.keySet().iterator(); while(iter.hasNext()) { Dozent d = (Dozent)iter.next(); System.out.println(d.getNachName() + " : " telefonBuch.get(d)); } } } //Schulz : 6789 //Müller : 2345 //Meier : 5678 //Schmidt : 1234 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Von Datenstrukturen zu Algorithmen... 49 Sortierung • Datenstruktur selbst hält Element sortiert • SortedSet oder SortedMap sortieren die Elemente bzw. Schlüssel gemäß ihrer „natürlichen Ordnung“ bzw. aufgrund eine explizit angegebenen „Vergleichers“ • Elemente explizit sortieren • Methode sort() aus der Klasse Collections • Elemente müssen paarweise vergleichbar sein • Implementieren des Interface Comparable • Implementieren einer Comparator-Klasse, die den Vergleich vornimmt Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Interface Comparable 50 einzige Methode • int compareTo(Object o) • Ergebnis < 0, falls das Objekt kleiner als Objekt o ist • Ergebnis = 0, falls das Objekt gleich Objekt o ist • Ergebnis > 0, falls das Objekt größer Objekt o ist Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Map Beispiel 51 public class Dozent implements Comparable { ... String nachName; ... public int compareTo(Object o) { Dozent d = (Dozent)o; return this.nachName.compareTo(d.nachName); } } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Map Beispiel 52 public class CollectionBsp4 { public void doIt() { SortedMap telefonBuch = new TreeMap(); Dozent Dozent Dozent Dozent schmidt = new Dozent("Schmidt"); meier = new Dozent("Meier"); mueller = new Dozent("Müller"); schulz = new Dozent("Schulz"); telefonBuch.put(schmidt,1234); telefonBuch.put(meier,5678); telefonBuch.put(mueller,2345); telefonBuch.put(schulz,6789); Iterator iter = telefonBuch.keySet().iterator(); while(iter.hasNext()) { Dozent d = (Dozent)iter.next(); System.out.println(d.getNachName() + " : " telefonBuch.get(d)); } } } //Meier : 5678 //Müller : 2345 //Schmidt : 1234 //Schulz : 6789 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Interface Comparator 53 einzige Methode • int compare(Object o1, Object o2) • Ergebnis < 0, falls o1 < o2 • Ergebnis = 0, falls o1 = o2 • Ergebnis > 0, falls o1 > o2 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Map Beispiel 54 public class CollectionBsp4 { public void doIt() { SortedMap telefonBuch = new TreeMap(new DozentComparator()); ... Iterator iter = telefonBuch.keySet().iterator(); while(iter.hasNext()) { Dozent d = (Dozent)iter.next(); System.out.println(d.getNachName() + " : " telefonBuch.get(d)); } } } public class DozentComparator implements Comparator { public int compare(Object o1, Object o2) { Dozent d1 = (Dozent)o1; Dozent d2 = (Dozent)o2; return d2.getNachName().compareTo(d1.getNachName()); } } // // // // Schulz : 6789 Schmidt : 1234 Müller : 2345 Meier : 5678 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Algorithmen 55 Beispiele • sortieren • kopieren • suchen und ersetzen • zählen, wie oft ein Element vorkommt • größtes, kleinstes Element suchen • rotieren • Reihenfolge umkehren • zufällig anordnen • Elemente vertauschen • ... Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Klassen Collections 56 Sammlung von statischen Methoden auf Collections Auswahl • static void sort(List list, Comparator c) • sortiert list gemäßt Comparator c • opt. mergesort, stabil, garantiert O(n log(n)) • static int frequency(Collection c, Object o) • zählt Häufigkeit von o in c • static void shuffle(List list, Random rnd) • ordnet Elemente zufällig an • static void swap(List list, int i, int j) • vertauscht i-tes und j-tes Element • static Collection synchronizedCollection(Collection c) • liefert eine Thread-sichere Collection für c • entsprechende Methoden für List, Map, Set • ... Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Beispielanwendung: SelectionSort 57 einfaches Sortierverfahren mit O(n2) Performance Prinzip: • Iteration über alle n Elemente der Liste • für jedes Elemente i: • finde Minimum m in der Teilliste (i,..,n) • vertausche m mit Element i Bsp: Liste l = {38, 04, 29, 12, 11} 38 04 29 ^ ^ 04 | 38 29 ^ 04 11 | 29 ^ 04 11 12 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite 12 11 12 11 ^ 12 38 ^ | 29 38 ^^ ... Beispielanwendung: SelectionSort 58 public static List sort(List l) { ListIterator it = l.listIterator(); while (it.hasNext()) { //aktuellen Index und aktuelles Objekt merken int currentIndex = it.nextIndex(); Comparable currentObject = (Comparable)it.next(); //Teilliste erzeugen List subList = l.subList(currentIndex,l.size()); //Minimum finden und Index merken Comparable minObj = (Comparable)Collections.min(subList); int minIndex = l.indexOf(minObj); //ggfs. Elemente vertauschen if (minObj.compareTo(currentObject) < 0) { Collections.swap(l,currentIndex, minIndex); } } return l; } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Eigene Collection Implementierung 59 Vererbung (extends) Implementierung (implements) <<interface>> Collection <<interface>> <<interface>> <<interface>> List Set Queue SortedSet Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite <<interface>> SortedMap BlockingQeue ArrayList TreeSet Map <<interface>> <<interface>> HashSet <<interface>> PriorityQueue LinkedList HashMap ArrayBlockingQueue TreeMap Eigene Collection Implementierung 60 Object Vererbung (extends) AbstractCollection AbstractSet AbstractList AbstractSequentialList HashSet TreeSet AbstractQueue PriorityQueue ArrayList LinkedList AbstractMap TreeMap HashMap ArrayBlockingQueue Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Eigene Collection Implementierung 61 abstrakte Klassen als „skeletal implementation“ der entsprechenden Interfaces minimieren den Aufwand, eigene Collections zu implementieren modifizierende Operationen lösen UnsupportedOperationException aus API Dokumentation erläutert, welche Methoden für eine eigene Implementierung zu überschreiben sind Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Eigene Collection - Stack 62 LIFO – Speicher spezielle Operationen als Stack Interface: public interface Stack { public boolean empty(); public void push (Object o); public Object pop(); public Object peek(); } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Eigene Collection - Stack 63 Implementierung als Collection: public class SimpleStack extends AbstractCollection implements Stack { LinkedList internList; public SimpleStack() { internList = new LinkedList(); } public void push(Object o) { public Iterator iterator() { return internList.iterator(); } internList.addFirst(o); } public int size() { return internList.size(); } public Object pop() { public boolean empty() { return internList.size() == 0; } public Object peek() { return internList.removeFirst(); } return internList.getFirst(); } } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Stack Beispiel 64 public interface Operation { public void eval(Stack s); } class Mal implements Operation { public void eval(Stack s) { int arg1 = (Integer)s.pop(); int arg2 = (Integer)s.pop(); s.push(arg2*arg1); } } class Plus implements Operation { public void eval(Stack s) { int arg1 = (Integer)s.pop(); int arg2 = (Integer)s.pop(); s.push(arg2+arg1); } } class Geteilt implements Operation { public void eval(Stack s) { int arg1 = (Integer)s.pop(); int arg2 = (Integer)s.pop(); s.push(arg2/arg1); } } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Stack Beispiel 65 public class PostFixEval { public static Operation PLUS = new Plus(); public static Operation MAL = new Mal(); public static Operation GETEILT = new Geteilt(); public int evaluate(Object[] expression) { Stack s = new SimpleStack(); for (int i = 0; i < expression.length; i++) { if (expression[i] instanceof Integer ) { s.push(expression[i]); } else { ((Operation)expression[i]).eval(s); } } return (Integer)s.peek(); } public static void main(String[] args) { PostFixEval e = new PostFixEval(); // 1+((3*4)/2) = 7 Object[] expression = {1,3,4,MAL,2,GETEILT,PLUS}; System.out.println(e.evaluate(expression)); }} Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Stack Beispiel 66 1 3 4 pu sh (3 ) pu sh (1 ) Eingabe: 1 * 2 / … Stack s = new SimpleStack(); for (int i = 0; i < expression.length; i++) { if (expression[i] instanceof Integer ) { s.push(expression[i]); } else { ((Operation)expression[i]).eval(s); } } … + pu sh (4 ) Seite 3 4 1 3 (3*4) 2 1 (3*4) 1 ((3*4)/2 ) 1 ) ev al (. . ev al (. . pu sh (2 ) ev al (. . ) ) 1 1+((3*4)/2) = 7 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Neuerungen in J2SE 5.0 67 Kritik an JDK1.2 Collections • umständliche Verwendung der Iteratoren, kein „for each“ • keine Typ-Sicherheit, da Collections nur allgemein Object aufnehmen List veranstaltungen = new ArrayList(); veranstaltungen.add( new Veranstaltung(“SE1“) ); veranstaltungen.add( new Object() ); Iterator listIt = veranstaltungen.listIterator(); while( listIt.hasNext() ) { Veranstaltung temp = (Veranstaltung)listIt.next(); temp.getTitel(); ... } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Veranstaltung titel : String sws : int schein : boolean zeit : Calendar add(Teilnehmer t) Neuerungen in J2SE 5.0 68 Generics (grob) • Collections lassen sich für einen bestimmten Typ parametrisieren • Compiler meldet Fehler, wenn falscher Typ verwendet wird • erhöht Typsicherheit und vermeidet Laufzeitfehler (ClassCastException) List<Veranstaltung> veranstaltungen = new ArrayList<Veranstaltung>(); veranstaltungen.add( new Veranstaltung(“SE1“) ); // compile Fehler : veranstaltungen.add( new Object() ); Iterator<Veranstaltung> listIt = veranstaltungen.listIterator(); while( listIt.hasNext() ) { Veranstaltung temp = listIt.next(); temp.getTitel(); ... } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Neuerungen in J2SE 5.0 69 Interface Iterable • einzige Methode im Interface • Iterator<T> iterator() • Interface wird von allen Collectionklassen implementiert Erweitertes „for“ möglich List<Veranstaltung> veranstaltungen = new ArrayList<Veranstaltung>(); veranstaltungen.add( new Veranstaltung(“SE1“) ); for (Veranstaltung v : veranstaltungen) { v.getTitel(); ... } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite „Alte Collections“ 70 dargestelltes Collection Framework existiert seit JDK 1.2 vorher gab es aber auch schon Collection Klassen • Vector • entspricht ArrayList • Thread-sicher (synchronized) • implementiert jetzt auch Interface List • Stack • leitetet von Vector ab • bietet Operationen wie im vorigen Beispiel an • Enumeration • entspricht Iterator • längere Methodennamen und irreführender Name • Hashtable • entspricht HashMap • Thread-sicher • implemetiert jetzt auch Interface Map Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java Collections Framework 71 Quellen • • • • • http://java.sun.com/j2se/1.5.0/docs/api/ http://java.sun.com/docs/books/tutorial/collections/index.html http://java.sun.com/j2se/1.5.0/docs/guide/collections/index.html http://www.jeckle.de/vorlesung/java/script.html http://www.javabuch.de/ (online Version von Guido Krügers Handbuch der Java-Programmierung 4. Auflage) • http://www.galileocomputing.de/openbook/javainsel4/ (online Version von Christian Ullenbooms „Java ist auch eine Insel“ 4. Auflage)