Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite 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/ 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 API Dokumentation 3 Java Klassenbibliothek 2 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite 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 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite 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. 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 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Java Collections Framework 7 Seite Übersicht über die wichtigsten Interfaces und Implementierungen Collection <<interface>> List Set SortedSet HashSet Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Queue LinkedList PriorityQueue Collection <<interface>> <<interface>> Map List Set <<interface>> HashSet TreeMap 9 Queue Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Map <<interface>> SortedMap BlockingQeue ArrayList TreeSet <<interface>> <<interface>> SortedSet HashMap Interface Collection <<interface>> <<interface>> SortedMap ArrayBlockingQueue Vererbung (extends) Implementierung (implements) <<interface>> <<interface>> BlockingQeue ArrayList TreeSet <<interface>> <<interface>> <<interface>> Übersicht über die wichtigsten Interfaces und Implementierungen Vererbung (extends) Implementierung (implements) <<interface>> <<interface>> Java Collections Framework 8 PriorityQueue LinkedList HashMap ArrayBlockingQueue TreeMap Interface Collection 10 verbindliche Operationen • boolean contains(Object o) „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 • 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 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite 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 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 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Beispiel 13 Seite import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.HashSet; import java.util.Collection; import java.util.Iterator; public class CollectionBsp1 { public static void main(String[] args) { public class CollectionBsp1 { public static void main(String[] args) { Collection c = new ArrayList(); Collection c = new HashSet(); for (int i = 0; i < 10; i++) { c.add(i); } for (int i = 0; i < 10; i++) { c.add(i); } Iterator iterator = c.iterator(); Iterator iterator = c.iterator(); while( iterator.hasNext() ) { System.out.print( iterator.next() + " " ); } while( iterator.hasNext() ) { System.out.print( iterator.next() + " " ); } } } } } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Listen 15 Seite Collection <<interface>> <<interface>> List Set SortedSet TreeSet Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Queue LinkedList PriorityQueue zusätzliche verbindliche und optionale Operationen bieten speziellen ListIterator mit erweiterter Funktionalität Implementierungen • ArrayList Map • • • • <<interface>> SortedMap BlockingQeue ArrayList Liste oder Sequenz von Objekten, geordnet doppelte Elemente erlaubt Einfügen von null erlaubt <<interface>> <<interface>> <<interface>> HashSet <<interface>> • Listenimplementierung als doppelt verkettete Liste • zusätzliche Operationen zum Einfügen/Entfernen/Zugriff auf Anfang und Ende der Liste TreeMap Listen 17 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite 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.) 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 HashMap ArrayBlockingQueue Listen 16 Vererbung (extends) Implementierung (implements) <<interface>> Seite Beispiel - Anpassbarkeit 14 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 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Listen - Beispiel 20 zusätzliche Operation zu herkömmlichen Iterator verbindliche Operationen • boolean hasPrevious() • true, falls es noch vorhergehende Elemente existieren • Object previous() dozent Veranstaltung • liefert das vorhergehende Element titel : String sws : int schein : boolean zeit : Calendar • int nextIndex() • liefert den Index des nächsten mit next() gelieferten Elements • int previousIndex() * 1 Dozent name : String email : String buero : int • 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 21 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite 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); 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 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 Implementierungen 23 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Mengen 24 ArrayList und LinkedList sind konkrete Listenimplementierungen Wann ist welche Liste sinnvoll? Performancevergleich • LinkedList Vererbung (extends) Implementierung (implements) <<interface>> Collection • 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 <<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 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Mengen 25 Seite 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 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 • keine garantierte Ordnung der Elemente bei Iteration • basiert auf HashMap • daher O(1) Performance für Basisoperationen (add, contains and remove) • Object last() • liefert das „größte“ Element der Menge • LinkedHashSet • SortedSet subSet(Object fromElement, Object toElement) • leitet von HashSet ab, garantiert aber die Reihenfolge der Elemente (Einfügereihenfolge) • liefert die Teilmenge mit Elementen „größer gleich“ fromElement und „echt kleiner“ als toElement • 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 • SortedSet tailSet(Object fromElement) • liefert die Teilmenge mit Elementen „größer gleich“ fromElement Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Mengen Beispiel 27 Seite dozent Veranstaltung titel : String sws : int schein : boolean zeit : Calendar * 1 Interface SortedSet 26 Mengen Beispiel 28 public class Veranstaltung { Dozent Set teilnehmer; name : String email : String buero : int public Veranstaltung(String titel, int sws, boolean schein, Dozent dozent, Calendar zeit) { ... this.teilnehmer = new HashSet(); } add(Teilnehmer t) * public void addTeilnehmer(Teilnehmer t) { teilnehmer.add(t); } * Teilnehmer public Set getTeilnehmer() { return teilnehmer; } ... name : String matrikel : int } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Mengen Beispiel 29 Seite Veranstaltung vl1 = new Veranstaltung(..); Veranstaltung vl2 = new Veranstaltung(..); Teilnehmer Teilnehmer Teilnehmer Teilnehmer Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig 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(); 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 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Schlangen 31 Seite Collection <<interface>> <<interface>> List Set <<interface>> Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Map <<interface>> SortedSet <<interface>> SortedMap BlockingQeue ArrayList TreeSet <<interface>> Queue <<interface>> HashSet 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 Vererbung (extends) Implementierung (implements) <<interface>> HashMap PriorityQueue LinkedList Schlangen 32 ArrayBlockingQueue TreeMap Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Schlangen – Interface Queue 33 Seite Schlangen – Interface BlockingQueue 34 zusätzliche verbindliche Operationen • Object element() zusätzliche optionale Operationen • boolean add(Object o) • fügt o sofort ein, löst IllegalStateException aus, falls nicht möglich • liefert erstes Element der Schlange, entfernt es aber nicht, löst NoSuchElementException aus, falls Schlange leer • int drainTo(Collection c) • entfernt alle Elemente der Qeue und fügt sie in c ein • int drainTo(Collection c, int maxElements) • boolean offer(Object o) • entfernt maximal maxElements und fügt sie in c ein • liefert true, falls o in die Schlange eingefügt werden konnte • boolean offer(Object o, long timeout, TimeUnit unit) • fügt o ein, wartet maximal timeout Zeiteineinheiten (unit), falls nicht sofort möglich • Object peek() • liefert erstes Element der Schlange, entfernt es aber nicht, liefert null, falls Schlange leer • Object poll(long timeout, TimeUnit unit) • entfernt das erste Element der Schlange, wartet timeout Zeiteinheiten (unit), falls nicht sofort möglich • Object poll() • void put(Object o) • liefert erstes Element der Schlange und entfernt es, liefert null, falls Schlange leer • 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 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 • Object take() • entfernt das erste Element der Schlange, wartet, falls nicht sofort möglich Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Schlangen Beispiel 35 Seite dozent Veranstaltung titel : String sws : int schein : boolean zeit : Calendar BlockingQueue : prueflinge add(Teilnehmer t) pruefung() * 1 Dozent name : String email : String buero : int 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()); 1 Iterator it = teilnehmer.iterator(); * while(it.hasNext()) { Teilnehmer t = (Teilnehmer)it.next(); TeilnehmerThread p = new TeilnehmerThread(t ,this); p.run(); } Teilnehmer name : String matrikel : int } } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Schlangen Beispiel 37 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Schlangen Beispiel 38 public class DozentThread extends Thread { protected Veranstaltung veranstaltung; protected Dozent dozent; public class TeilnehmerThread extends Thread { private Teilnehmer teilnehmer; private Veranstaltung veranstaltung; public void run() { BlockingQueue pruefling = veranstaltung.getPrueflinge(); 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){ 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 39 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Assoziative Speicher (Maps) 40 Beispiel: Pruefungen fuer die VL Software Systems von Meier Vererbung (extends) Implementierung (implements) <<interface>> 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. Collection 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 <<interface>> <<interface>> List Set Seite Assoziative Speicher 41 HashSet Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig • 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) <<interface>> Map <<interface>> SortedSet Seite 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 Queue <<interface>> <<interface>> SortedMap BlockingQeue ArrayList TreeSet Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig <<interface>> PriorityQueue LinkedList HashMap ArrayBlockingQueue TreeMap 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 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Interface SortedMap 44 optionale Operationen • void clear() verbindliche Operationen • Comparator comparator() • liefert den Comparator, der mit dem Map assoziiert ist • entfernt alle Schlüssel-Wert-Paare • Object put(Object key, Object value) • Object firstKey() • legt neuen Eintrag mit Schlüssel key und Wert value an, ersetzt ggfs. vorhandene Einträge • liefert den „kleinsten“ Schlüssel • SortedMap headMap(Object toKey) • void putAll(Map t) • liefert ein Teilmapping mit Schlüsseleinträgen „echt kleiner“ als toKey • fügt alle Einträge aus t ein • Object remove(Object key) • Object lastKey() • entfernt den Eintrag mit Schlüssel key und liefert entsprechenden Wert zurück • 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 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Telefonbuch • zu gegebenem Dozenten (Schlüssel) wird Telefonnummer (Wert) gesucht public class CollectionBsp4 { public void doIt() { Map telefonBuch = new HashMap(); Dozent Dozent Dozent Dozent 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"); 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); 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(schmidt)); // true System.out.println(telefonBuch.get(schmidt)); // 1234 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 46 Map Beispiel 47 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Lösung: Überschreiben von hashCode() und equals() public class Dozent { 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 ... String nachName; ... //@Override public int hashCode() { return nachName.hashCode(); } 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); //@Override public boolean equals(Object obj) { if (obj instanceof Dozent) { return ((Dozent)obj).getNachName().equals(nachName); } return false; } 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 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Interface Comparable 50 Sortierung • Datenstruktur selbst hält Element sortiert einzige Methode • int compareTo(Object o) • SortedSet oder SortedMap sortieren die Elemente bzw. Schlüssel gemäß ihrer „natürlichen Ordnung“ bzw. aufgrund eine explizit angegebenen „Vergleichers“ • 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 • 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 Map Beispiel 51 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite public class Dozent implements Comparable { Map Beispiel 52 public class CollectionBsp4 { public void doIt() { SortedMap telefonBuch = new TreeMap(); Dozent Dozent Dozent Dozent ... String nachName; ... 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); public int compareTo(Object o) { Dozent d = (Dozent)o; return this.nachName.compareTo(d.nachName); } } 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 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite einzige Methode • int compare(Object o1, Object o2) Map Beispiel 54 public class CollectionBsp4 { public void doIt() { SortedMap telefonBuch = new TreeMap(new DozentComparator()); • Ergebnis < 0, falls o1 < o2 • Ergebnis = 0, falls o1 = o2 • Ergebnis > 0, falls o1 > o2 ... 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 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Algorithmen 55 Seite Klassen Collections 56 Sammlung von statischen Methoden auf Collections Auswahl • static void sort(List list, Comparator c) 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 • ... • 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 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Beispielanwendung: SelectionSort 57 Seite einfaches Sortierverfahren mit O(n2) Performance Prinzip: • Iteration über alle n Elemente der Liste • für jedes Elemente i: 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(); • 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 //Teilliste erzeugen List subList = l.subList(currentIndex,l.size()); 12 11 12 11 ^ 12 38 ^ | 29 38 ^^ Beispielanwendung: SelectionSort 58 //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 Eigene Collection Implementierung 59 Seite Vererbung (extends) Implementierung (implements) <<interface>> Collection Eigene Collection Implementierung 60 Object Vererbung (extends) AbstractCollection <<interface>> Set <<interface>> List <<interface>> Queue <<interface>> Map AbstractSet <<interface>> <<interface>> SortedSet HashSet TreeSet LinkedList PriorityQueue AbstractQueue AbstractMap SortedMap BlockingQeue ArrayList AbstractList <<interface>> AbstractSequentialList HashMap ArrayBlockingQueue TreeMap HashSet TreeSet PriorityQueue ArrayList LinkedList TreeMap HashMap ArrayBlockingQueue Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Eigene Collection Implementierung 61 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Eigene Collection - Stack 62 abstrakte Klassen als „skeletal implementation“ der entsprechenden Interfaces minimieren den Aufwand, eigene Collections zu implementieren modifizierende Operationen lösen UnsupportedOperationException aus LIFO – Speicher spezielle Operationen als Stack Interface: public interface Stack { public boolean empty(); API Dokumentation erläutert, welche Methoden für eine eigene Implementierung zu überschreiben sind 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 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Stack Beispiel 64 Implementierung als Collection: public interface Operation { public void eval(Stack s); } 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() { 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); } } return internList.removeFirst(); } return internList.getFirst(); } } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Stack Beispiel 65 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Stack Beispiel 66 public class PostFixEval { Eingabe: 1 3 4 * 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); } } … / + PostFixEval e = new PostFixEval(); // 1+((3*4)/2) = 7 Object[] expression = {1,3,4,MAL,2,GETEILT,PLUS}; System.out.println(e.evaluate(expression)); }} pu sh (4 ) pu sh (3 ) 3 4 1 3 (3*4) 2 1 (3*4) 1 ((3*4)/2 ) 1 ) ev al (. . ev al (. . ) ) 1 pu sh (2 ) public static void main(String[] args) { 1 ev al (. . 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(); } pu sh (1 ) public static Operation PLUS = new Plus(); public static Operation MAL = new Mal(); public static Operation GETEILT = new Geteilt(); 1+((3*4)/2) = 7 Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Neuerungen in J2SE 5.0 67 Seite 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 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) Veranstaltung titel : String sws : int schein : boolean zeit : Calendar List<Veranstaltung> veranstaltungen = new ArrayList<Veranstaltung>(); veranstaltungen.add( new Veranstaltung(“SE1“) ); // compile Fehler : veranstaltungen.add( new Object() ); Iterator<Veranstaltung> listIt = veranstaltungen.listIterator(); add(Teilnehmer t) Neuerungen in J2SE 5.0 69 while( listIt.hasNext() ) { Veranstaltung temp = listIt.next(); temp.getTitel(); ... } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Interface Iterable • einzige Methode im Interface • Iterator<T> iterator() • Interface wird von allen Collectionklassen implementiert Erweitertes „for“ möglich „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 List<Veranstaltung> veranstaltungen = new ArrayList<Veranstaltung>(); veranstaltungen.add( new Veranstaltung(“SE1“) ); • leitetet von Vector ab • bietet Operationen wie im vorigen Beispiel an • Enumeration for (Veranstaltung v : veranstaltungen) { v.getTitel(); ... } • 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)