22-st-programming-ag..
Transcription
22-st-programming-ag..
Schnittstellen und Implementierungen im Collection-Framework 22) Programmieren gegen Schnittstellen "Der "DerAufrufer Aufruferprogrammiert programmiertgegen gegendie die Schnittstelle, Schnittstelle, er befindet sich sozusagen im luftleeren er befindet sich sozusagen im luftleerenRaum." Raum." Siedersleben/Denert, Siedersleben/Denert, Wie Wiebaut bautman manInformationssysteme, Informationssysteme, Informatik-Spektrum Informatik-Spektrum, ,August August2000 2000 ► Version 12-0.3, 13.04.12 ► ► Softwaretechnologie, © Prof. Uwe Aßmann Technische Universität Dresden, Fakultät Informatik Prof. U. Aßmann, Softwaretechnologie, TU Dresden ► 1 Polymorphe Container durch Schnittstellen 2 Entwurfsmuster Iterator (Stream) 3 Auswahl von Implementierungen für Datenstrukturen 4 Persistente Datenhaltung ► <<interface>> List Implementierung (implements) <<interface>> Set ArrayList <<interface>> Queue <<interface>> Map <<interface>> SortedSet <<interface>> SortedMap LinkedList Vector PriorityQueue HashSet HashMap TreeSet TreeMap Stack 1 2 Typanpassungen mit Schnittstellen: Geordnete Listen mit ArrayList (1) Anwendungsbeispiel mit ArrayList (falsch!) ... public void sonderpreis (int pos, int preis) { liste.get(pos).einzelpreis(preis); } ... import java.util.ArrayList; ... class Bestellung { private String kunde; private ArrayList liste; private int anzahl = 0; ► public Bestellung(String kunde) { this.kunde = kunde; this.liste = new ArrayList(); Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden Vererbung (extends) <<interface>> Collection } public void neuePosition (Bestellposition b) { liste.add(b); } public void loeschePosition (int pos) { liste.remove(pos); } ... Compilermeldung: „Method einzelpreis(int) not found in class java.lang.Object.“ ? liste.get(pos).einzelpreis(preis); ArrayList Object defi niert auf Bestellposition Spezialisierung von Object auf Bestellposition? 3 4 Typanpassungen auf Elementtypen Anwendungsbeispiel mit ArrayList (2) * public void sonderpreis (int pos, int preis) { ((Bestellposition)liste.get(pos)).einzelpreis(preis); } Object Bestellung – kunde: String – anzahl: int 1 java.util.ArrayList add(Object o) liste get(pos: int): Object ... public int auftragssumme() { int s = 0; for(int i=0; i<liste.size(); i++) s += ((Bestellposition)liste.get(i)).positionspreis(); return s; } Bestellposition Typanpassung (cast): • Operationen der Oberklasse passen immer auch auf Objekte der Unterklasse • Operationen der Unterklasse auf Objekte einer Oberklasse anzuwenden, erfordert explizite Typanpassung (dynamic cast): ( Typ ) Objekt hier: (Bestellposition)liste.get(pos) Geordnete Collections II java.util.LinkedList (Auszug) Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden * Zusicherung: Alle von einem Bestellung-Objekt über die liste-Assoziation erreichbaren Objekte sind aus der Klasse Bestellposition. } public void print () { System.out.println("Bestellung fuer Kunde "+kunde); for(int i=0; i<liste.size(); i++) System.out.println(liste.get(i)); System.out.println("Auftragssumme: "+auftragssumme()); System.out.println(); } Online: Bestellung1.java 5 6 22.1 Polymorphe Container durch Schnittstellen public class LinkedList implements List { public boolean add (Object o); public boolean remove (Object o); public void clear(); public boolean isEmpty(); public boolean contains (Object o); public int size(); public Object get (int index); public Object set (int index, Object element) public Object remove (int index); public int indexOf (Object o); public void addFirst (Object o); public void addLast (Object o); ... Anwendungsbeispiel Online: } mit LinkedList: Bestellung3.java 7 Softwaretechnologie, © Prof. Uwe Aßmann Technische Universität Dresden, Fakultät Informatik 8 Programmieren gegen Schnittstellen -- Polymorphe Container class Bestellung { Polymorphe Container: Wechsel der Datenstruktur ! List ist ein Interface, keine Klasse ! • ArrayList: class Bestellung { private String kunde; private List liste; private String kunde; private List liste; public Bestellung(String kunde) { this.kunde = kunde; this.liste = new ArrayList(); } ... ... // Konstruktor sh. nächste Folien public void loeschePosition (int pos) { liste.remove(pos); } public void sonderpreis (int pos, int preis) { ((Bestellposition)liste.get(pos)).einzelpreis(preis); } Standardalgorithmen in der Algorithmenklasse java.util.Collections – – class Bestellung { private String kunde; private List liste; public Bestellung(String kunde) { this.kunde = kunde; this.liste = new LinkedList(); } ... Code muß bei Wechsel der Datenstruktur nur an einer Stelle (Konstruktor) geändert werden ! 10 Prädikat-Schnittstellen (...able Schnittstellen) Algorithmenklassen (Hilfsklassen) enthalten Algorithmen, die auf einer Familie von anderen Klassen arbeiten – • LinkedList: 9 ► Prädikat-Schnittstellen drücken bestimmte Eigenschaft einer Klasse aus. Sie werden oft mit dem Suffix “able” benannt: – Hier: java.util.Collections enthält Algorithmen auf beliebigen Klassen, die das Collection- bzw. List-Interface implementieren Bei manchen Operationen ist Ordnung auf Elementen vorausgesetzt. Achtung: Statische Operationen! – – ► Prof. U. Aßmann, Softwaretechnologie, TU Dresden ► Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden public void neuePosition (Bestellposition b) { liste.add(b); } ! List ist ein Interface, keine Klasse ! public class Collections { public static Object max (Collection coll); public static Object min (Collection coll); public static int binarySearch(List list, Object key); public static void reverse (List list); public static void sort (List list) ... } 11 Iterable Clonable Serializable Beispiel: geordnete Standarddatentypen (z.B. String oder List) implementieren die Prädikatschnittstelle Comparable: public interface Comparable { public int compareTo (Object o); } ► Resultat ist kleiner/gleich/größer 0: genau dann wenn "this" kleiner/gleich/größer als Objekt o 12 Schnittstellen und Klassen (Erweiterung) 22.2 Entwurfsmuster Iterator (Stream) Schnittstelle (interface) (Konkrete) Klasse Abstrakte Klasse Prädikat-Schnittstelle Algorithmenklasse ► Name: Iterator (auch: Stream, Cursor, Enumeration) ► Problem: Sequentielles, polymorphes Durchlaufen der Elemente eines strukturieren Objekts oder einer Collection. – Aufzählen der in einem “Behälter” befindlichen Elemente durch Herausziehen (pull) mit Hilfe einer Iteratormethode – Keine Aussage über die Reihenfolge! <<interface>> java.util.Iterator Iterator Lösung: Iterator {abstract} next() hasNext() Container elements(): Iterator <<create>> 14 Iterator-Beispiel in der JDK (ArrayList) pull.. IteratorMethode ConcreteIterator * hasNext() next() Aggregate Bestellung – kunde: String – anzahl: int 1 Concrete Iterator java.util.ArrayList add(o: Object) liste get(pos: int): Object <<create>> iterator(): Iterator ... Klassenname nicht * Prof. U. Aßmann, Softwaretechnologie, TU Dresden Entwurfsmuster Iterator (Implementierungsmuster) ► Softwaretechnologie, © Prof. Uwe Aßmann Technische Universität Dresden, Fakultät Informatik 13 Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden Klassenbegriff Element bekannt, weil privat (z.B. ArrayListIterator) Object Element 15 16 Iterator-Implementierungsmuster Verwendungsbeispiel: import java.util.Iterator; ... class Bestellung { List List list; list; .. .. Iterator Iterator ii == list.iterator(); list.iterator(); while while (i.hasNext()) (i.hasNext()) {{ doSomeThing(i.next()); doSomeThing(i.next()); }} private String kunde; private ArrayList liste; Vorteile: ► – – – Iteratoren und Iteratormethoden erlauben, die Netz-Struktur einer komplexten Datenstruktur nach außen hin zu verbergen (Geheimnisprinzip) Sie erlauben bedarfsgesteuerte Berechnungen (processing on demand, lazy processing), weil sie nicht alle Objekte der komplexen Datenstruktur herausgeben, sondern nur die, die wirklich benötigt werden Iteratoren können “unendliche” Datenstrukturen repräsentieren, z.B. die natürlichen Zahlen 17 Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden ► Anwendungsbeispiel mit Iteratoren Online: Bestellung2.java For-Schleifen auf IterablePrädikatschnittstellen In vielen Programmiersprachen (Sather, Scala) stehen Iteratormethoden (stream methods) als spezielle Prozeduren zur Verfügung, die die Unterobjekte eines Objekts liefern können – Die yield-Anweisung gibt aus der Prozedur die Elemente zurück – Iterator-Prozedur kann mehrfach aufgerufen werden – Beim letzten Mal liefert sie null ► class class bigObject bigObject {{ private private List List subObjects; subObjects; public iterator public iterator Object Object deliverThem() deliverThem() {{ while while (i (i in in subObjects) subObjects) {{ yield yield i; i; }} }} }} 19 Erbt eine Klasse von Iterable, kann sie in einer vereinfachten forSchleife benutzt werden class class BillItem BillItem {{ int int price; price; }} class class Bill Bill {{ int int sum sum == 0; 0; private private List List billItems; billItems; public void public void sumUp() sumUp() {{ for (BillItem for (BillItem item: item: billItems) billItems) {{ sum sum += += item.price; item.price; }} class return class BillItem BillItem {{ int int price; price; }} return sum; sum; class }} class Bill Bill {{ int }} int sum sum == 0; 0; private private List List billItems; billItems; public public void void sumUp() sumUp() {{ for for (Iterator (Iterator ii == billItems.iterator(); billItems.iterator(); i.hasNext(); i.hasNext(); )) {{ item = i.next(); item = i.next(); sum sum += += item.price; item.price; }} return return sum; sum; }} }} Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden } 18 Iterator-Implementierungsmuster in modernen Sprachen ► ... public int auftragssumme() { Iterator i = liste.iterator(); int s = 0; while (i.hasNext()) s += ((Bestellposition)i.next()).positionspreis(); return s; } ... 20 Entwurfsmuster Senke (Implementierungsmuster) 22.2.2 Senken (Sinks) ► Name: Senke (auch: Ablage, sink, belt) ► Problem: Ablage eines beliebig großen Datenstromes. – – Prof. U. Aßmann, Softwaretechnologie, TU Dresden ► Softwaretechnologie, © Prof. Uwe Aßmann Technische Universität Dresden, Fakultät Informatik push ggf. mit Abfrage, ob noch freier Platz in der Ablage vorhanden Lösung: Sink {abstract} push() hasFreeSpace() Client push.. SinkMethode ConcreteSink 21 22 Erweiterung: Begriffshierarchie der Methodenarten 22.2.3 Channels (Pipes) Prof. U. Aßmann, Softwaretechnologie, TU Dresden Methode Zustandsverändernde Methoden Zustandsinvariante Methoden Iterator methoden Anfrage (query) Checker Modifikatoren Zustandsmodifikatoren Tester Senken Netzmodifikatoren Allgemeine Methoden RepräsentationsWechsler 23 Softwaretechnologie, © Prof. Uwe Aßmann Technische Universität Dresden, Fakultät Informatik 24 Channels in anderen Sprachen ► Name: Channel (auch: pipe, buffer, Kanal) ► Zweck: asynchrone Kommunikation zwischen zwei Komponenten durch Pufferung eines beliebig großen Datenstromes mit Hilfe eines Puffers buffer ► – Kombination von push- und pull-Methoden (Strom- und Ablagemethoden) – ggf. mit Abfrage, ob noch freier Platz in der Ablage vorhanden – ggf. mit Abfrage, ob noch Daten im Kanal vorhanden - buffer push() hasFreeSpace() ■ Shell-Skripte (Operator für pipes: “|”) Communicating Sequential Processes (CSP, Hoare): ♦ Operator für push: “?” ♦ Operator für pull: “!” ■ push of sink.. pull of stream.. next() hasNext() Client Prof. U. Aßmann, Softwaretechnologie, TU Dresden Channel Channels (pipes) kommen in vielen Sprachen als Konstrukte vor ■ ► Architectural Description Languages (ADL, Kurs CBSE) Sie sind ein elementares Muster für die Kommunikation von parallelen Prozessen (producer-consumer-Muster) ConcreteChannel 25 Weitere Implementierungen in der CollectionHierarchie 22.3 Auswahl von Implementierungen von Datenstrukturen Softwaretechnologie, © Prof. Uwe Aßmann Technische Universität Dresden, Fakultät Informatik 27 <<interface>> List 26 Vererbung (extends) <<interface>> Collection Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden Entwurfsmuster Channel (Pipe) (Implementierungsmuster) Implementierung (implements) <<interface>> Set <<interface>> Map <<interface>> SortedSet <<interface>> SortedMap ArrayList LinkedList Vector HashSet HashMap TreeSet Hashtable TreeMap 28 Welche Listen-Implementierung soll man wählen? Innere Schleifen bilden die „heißen Punkte“ (hot spots) eines Programms – Prof. U. Aßmann, Softwaretechnologie, TU Dresden ► – – Implementierung (implements) Optimierung von inneren Schleifen durch Auswahl von Implementierungen mit geeignetem Zugriffsprofil Gemessener relativer Aufwand für Operationen auf Listen: (aus Eckel, Thinking in Java, 2nd ed., 2000) – Vererbung (extends) <<interface>> Collection <<interface>> List Prof. U. Aßmann, Softwaretechnologie, TU Dresden ► Collection Framework (Überblick) (Mengen ohne Mehrfacheintrag) Stärken von ArrayList: wahlfreier Zugriff Stärken von LinkedList: Iteration, Einfügen und Entfernen irgendwo in der Liste Vector generell die langsamste Lösung Typ array ArrayList LinkedList Vector Lesen 1430 3070 16320 4890 Iteration 3850 12200 9110 16250 Einfügen -500 110 550 Entfernen -46850 60 46850 <<interface>> Set <<interface>> SortedSet LinkedList HashSet HashMap TreeSet Anwendungsbeispiel für Set <<interface>> Collection Warengruppe – name: String – lagerplatz: String // Query methods + boolean isEmpty(); + boolean contains(Object o); + boolean equals(Object o); + int hashCode(); + Iterator iterator(); Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden TreeMap 30 Ungeordnete Mengen: java.util.Set (Auszug) // Zustandsveränderer + boolean add (Object o); + boolean remove (Object o); + void clear(); <<interface>> SortedMap ArrayList 29 // Repräsentations-Trans// formierer + Object[] toArray(); <<interface>> Map <<interface>> Set // Query methods + Object get(int index); // Zustandsveränderer + boolean add (Object o); 31 + add (a: Artikel) + anzahl(): int 1 * Artikel – name: String – preis: int + preis(): int 32 java.util.HashSet (Auszug) <<interface>> Collection <<interface>> Set // Query methods + Object get(int index); // Zustandsveränderer + boolean add (Object o); // Repräsentations-Trans// formierer + Object[] toArray(); // Zustandsveränderer + boolean add (Object o); + boolean remove (Object o); + void clear(); (Anmerkung: Erläuterung von Hashfunktionen folgt etwas später !) <<interface>> HashSet // Konstruktor # HashSet(int initialCapacity, float loadFactor); + Object get(int index); + int hashCode() // Zustandsveränderer + boolean add (Object o); Duplikatsprüfung für Elemente in Mengen: Wann sind Objekte gleich? (1) ► 33 Vergleich mit Operation == : – Referenzgleichheit, d.h. physische Identität der Objekte – Typischer Fehler: Stringvergleich mit "==" (ist nicht korrekt, geht aber meistens gut!) Vergleich mit o.equals(): – deklariert in java.lang.Object – überdefiniert in vielen Bibliotheksklassen ● – z.B. java.lang.String für selbstdefinierte Klassen ● ● Standardbedeutung Referenzgleichheit bei Bedarf selbst überdefinieren ! (Ggf. für kompatible Definition der Operation o.hashCode() aus java.lang.Object sorgen) Online: Warengruppe1.java 35 class Warengruppe { private String name; private String lagerplatz; private Set inhalt; public Warengruppe (String name, String lagerplatz) { this.name = name; this.lagerplatz = lagerplatz; this.inhalt = new HashSet(); } public void add (Artikel a) { inhalt.add(a); } public int anzahl() { return inhalt.size(); } public String toString() { String s = "Warengruppe "+name+"\n"; Iterator it = inhalt.iterator(); while (it.hasNext()) { s += " "+(Artikel)it.next(); }; Online: } Warengruppe0.java } 34 Wann sind Objekte gleich? (2) Referenzgleichheit Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden ► Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden // Query methods + boolean isEmpty(); + boolean contains(Object o); + boolean equals(Object o); + int hashCode(); + Iterator iterator(); Anwendungsbeispiel mit HashSet public static void main (String[] args) { Warengruppe w1 = new Warengruppe("Moebel","L1"); w1.add(new Artikel("Tisch",200)); w1.add(new Artikel("Stuhl",100)); w1.add(new Artikel("Schrank",300)); w1.add(new Artikel("Tisch",200)); System.out.println(w1); } Systemausgabe beim Benutzen der Standard-Gleichheit: Warengruppe Moebel Tisch(200) Tisch(200) Schrank(300) Stuhl(100) Online: Warengruppe0.java 36 Wann sind Objekte gleich? (3) Referenzgleichheit java.util.SortedSet (Auszug) <<interface>> Collection } // Query methods + boolean isEmpty(); + boolean contains(Object o); + boolean equals(Object o); + int hashCode(); + Iterator iterator(); Warengruppe w2 = new Warengruppe("Moebel","L2"); w2.add(tisch); w2.add(stuhl); w2.add(schrank); w2.add(tisch); System.out.println(w1); Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden public static void main (String[] args) { Artikel tisch = new Artikel("Tisch",200); Artikel stuhl = new Artikel("Stuhl",100); Artikel schrank = new Artikel("Schrank",300); <<interface>> Set // Query methods + Object get(int index); // Zustandsveränderer + boolean add (Object o); // Repräsentations-Trans// formierer + Object[] toArray(); // Zustandsveränderer + boolean add (Object o); + boolean remove (Object o); + void clear(); Systemausgabe: Warengruppe Moebel Schrank(300) Tisch(200) Stuhl(100) Es wurde zweifach dasselbe Tisch-Objekt übergeben ! (Gleiches Verhalten bei Strukturgleichheit, s. Warengruppe1.java) <<interface>> SortedSet + Object first(); + Object last() 37 38 Anwendungsbeispiel mit TreeSet java.util.TreeSet ► ► java.util.TreeSet implementiert ein geordnete Menge mit Hilfe eines Baumes und benötigt zum Sortieren dessen die Schnittstelle Comparable Modifi kation der Klasse Warengruppe: private Set inhalt; } ► Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden class Warengruppe { public Warengruppe (…) { … this.inhalt = new TreeSet(); } … Aber Systemreaktion: Exception in thread "main" java.lang.ClassCastException: Artikel at java.util.TreeMap.compare(TreeMap.java, Compiled Code) ► in java.util.TreeSet: public class TreeSet … implements SortedSet … { … } 39 ► Artikel muss zusätzlich von Schnittstelle Comparable erben ► Modifikation der Klasse „Artikel“: class Artikel implements Comparable { ... public int compareTo (Object o) { return name.compareTo(((Artikel)o).name); } } Systemausgabe: Warengruppe Moebel Schrank(300) Stuhl(100) Tisch(200) Online: Warengruppe3.java 40 Collection Framework (Überblick) (Maps) HashSet oder TreeSet? Typ HashSet TreeSet ► Enthalten 106,5 177,4 Iteration 39,39 40,04 <<interface>> List Stärken von HashSet: – ► Einfügen 36,14 150,6 in allen Fällen schneller ! Stärken von TreeSet: – erlaubt Operationen für sortierte Mengen 41 Eine Map ist ein „assoziativer Speicher“ (associative array), der Objekte als Werte (value) unter Schlüsseln (key) zugreifbar macht – Ein Schlüssel liefert einen Wert (Funktion). Map liefert funktionale Abhängigkeit zwischen Schlüssel und Wert <<interface>> Map // Anfragen (query methods) + int size(); + boolean isEmpty(); + boolean containsKey(Object key); + boolean containsValue(Object value); + Object get (Object key); + int hashCode(); + Iterator iterator(); + Set keySet(); + Set values(); <<interface>> Set <<interface>> HashMap // Zustandsveränderer + void clear(); + Object put (Object key, Object value); + boolean remove (Object o); 43 <<interface>> Map <<interface>> SortedSet <<interface>> SortedMap ArrayList HashSet LinkedList HashMap TreeSet Katalog – name: String + put (code: String, a: Artikel) + get (code: String): Artikel + anzahl(): int Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden – Implementierung (implements) TreeMap Anwendungsbeispiel: Verfeinerung von qualifizierten Relationen java.util.Map (Auszug) ► Vererbung (extends) <<interface>> Collection Gemessener relativer Aufwand für Operationen auf Mengen: (aus Eckel, Thinking in Java, 2nd ed., 2000) Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden ► code: String * 42 HashMap ist eine sehr günstige Umsetzung für qualifizierte Assoziationen: Der Qualifikator bildet den Schlüssel; die Zielobjeke den Wert Hier: •Schlüssel: code:String •Wert: a:Artikel 1 Artikel – name: String – preis: int + preis(): int 44 Testprogramm für Anwendungsbeispiel: Speicherung der Waren mit Schlüsseln class Katalog { private String name; private Map inhalt; public Katalog (String name) { this.name = name; this.inhalt = new HashMap(); } public void put (String code, Artikel a) { inhalt.put(code,a); } public int anzahl() { return inhalt.size(); } public Artikel get (String code) { return (Artikel)inhalt.get(code); } ... Online: } Katalog.java public static void main (String[] args) { Artikel tisch = new Artikel("Tisch",200); Artikel stuhl = new Artikel("Stuhl",100); Artikel schrank = new Artikel("Schrank",300); Artikel regal = new Artikel("Regal",200); Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden Anwendungsbeispiel mit HashMap Katalog k = new Katalog("Katalog1"); Systemausgabe: k.put("M01",tisch); Katalog Katalog1 k.put("M02",stuhl); M03 -> Schrank(300) M02 -> Stuhl(100) k.put("M03",schrank); M01 -> Tisch(200) System.out.println(k); Katalog Katalog1 k.put("M03",regal); M03 -> Regal(200) M02 -> Stuhl(100) System.out.println(k); M01 -> Tisch(200) } put(...) überschreibt vorhandenen Eintrag (Ergebnis = vorhandener Eintrag). Ordnung auf den Schlüsseln: SortedMap (Implementierung z.B.TreeMap). 45 46 Prinzip der Hashtabelle Kollision beim Einstechen Effekt von hashtab.put(key,value) Typischerweise wird der Schlüssel (key) transformiert: – Prof. U. Aßmann, Softwaretechnologie, TU Dresden – ► Das Objekt liefert seinen Hashwert mit der Hash-Funktion hashCode() Mit dem Hashwert wird in eine Hashtabelle eingestochen, d.h. der Hashwert wird auf einen Zahlenbereich modulo der Kapazität der Hashtabelle abgebildet, d.h., der Hashwert wird auf die Hashtabelle “normiert” hashtab Object hashCode(): int key: Object value: Object value: Object capacity Bei nicht eindeutigen Schlüsseln, oder auch durch die Normierung, werden Einträge doppelt “adressiert” (Kollision) 0 key1: Object 0 key.hashCode() Die Hashfunktion ist mehrdeutig (nicht injektiv): – Prof. U. Aßmann, Softwaretechnologie, TU Dresden ► 47 value1: Object key2: Object value2: Object key1.hashCode() value?: Object = key2.hashCode() Verfahren zur Kollisionsauflösung: – Überlauflisten – Überlauf in der Hashtabelle capacity 48 Suche nach vorgefertigten Lösungen (Collection-Klassen der Bibliothek) Vorgehensweise beim Datenstruktur-Entwurf Collection Identifikation der Anforderungen an die Datenstruktur: Funktionalität, häufig benutzte Operationen Einfügen eines Elements Entfernen eines Elements Aufzählen aller Elemente "ist enthalten"-Abfrage dynamisch erweiterbar Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden Abstraktion auf die wesentlichen Eigenschaften Suche nach vorgefertigten Lösungen (Nutzung der Collection-Bibliothek) Ggf. Experimente (experimentelle Prototypen) Anpassung an vorgefertigte Lösung Map Entwicklung einer neuartigen Lösung Einfügereihenfolge relevant? Einfügen eines Werts für einen Schlüssel Entfernen eines Schlüssel/Wert-Paars Abfrage eines Werts für einen Schlüssel "ist enthalten"-Abfrage für Schlüssel dynamisch erweiterbar Sortierung der Schlüssel relevant? SortedMap nein ja List Set Sortierung relevant? Abfrage an i-ter Position Ersetzen an i-ter Position Entfernen an i-ter Position SortedSet kleinstes/größtes Element Elemente "über"/"unter" x 49 50 Realisierung von ungeordneten Assoziationen mit Set Beispiel: Realisierung von Assoziationen A * assoc B A Datenstruktur im A-Objekt für B-Referenzen 1) Assoziation anlegen 2) Assoziation entfernen 3) Durchlaufen aller bestehenden Assoziationen zu B-Objekten 4) Manchmal: Abfrage, ob Assoziation zu einem B-Objekt besteht 5) Keine Obergrenze der Multiplizität gegeben * B class A { private Set assoc; ... Realisierung 1) Einfügen (ohne Reihenfolge) 2) Entfernen (ohne Reihenfolge) 3) Aufzählen aller Elemente Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden Anforderung assoc 4) "ist enthalten"-Abfrage 5) Maximalanzahl der Elemente unbekannt; dynamisch erweiterbar public void addAssoc (B b) { assoc.add(b); } public boolean testAssoc (B b) { return assoc.contains(b); } public A { ... assoc = new HashSet(); } Set 51 52 Beispiel: Raumverwaltung Raumverwaltung: Freien Raum suchen static Besprechungsraum freienRaumSuchen (int groesse, Hour beginn, int dauer) class Raumverwaltung { ► Suche unter vorhandenen Räumen nach Raum mit mindestens der Kapazität groesse, aber möglichst klein. – Datenstruktur für vorhandene Räume in Klasse Raumverwaltung ► Prof. U. Aßmann, Softwaretechnologie, TU Dresden » SortedSet (Elemente: Besprechungsraum) Überprüfung eines Raumes, ob er für die Zeit ab beginn für die Länge dauer bereits belegt ist. – Operation in Klasse Besprechungsraum: boolean frei (Hour beginn, int dauer) – Datenstruktur in Klasse Besprechungsraum für Zeiten (Stunden): » Set (Elemente: Hour) ► Zusatzanforderung (Variante): Überprüfung, welcher andere Termin eine bestimmte Stunde belegt. – Datenstruktur in Klasse Besprechungsraum: } » Map (Schlüssel: Hour, Wert: Teambesprechung) // Suche freien Raum aufsteigend nach Größe static Besprechungsraum freienRaumSuchen (int groesse, Hour beginn, int dauer) { Besprechungsraum r = null; boolean gefunden = false; Iterator it = vorhandeneRaeume.iterator(); while (! gefunden && it.hasNext()) { r = (Besprechungsraum)it.next(); if (r.grossGenug(groesse)&& r.frei(beginn,dauer)) gefunden = true; }; if (gefunden) return r; else return null; } ... 53 54 Temporäre und persistente Daten 22.4 Persistente Datenhaltung (Files als Channels) ► ► Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden // Vorhandene Raeume, aufsteigend nach Größe sortiert // statisches Klassenattribut und -methode private static SortedSet vorhandeneRaeume = new TreeSet(); Art is long, and Time is fleeting. H. W. Longfellow Softwaretechnologie, © Prof. Uwe Aßmann Technische Universität Dresden, Fakultät Informatik 55 Daten sind – temporär, wenn sie mit Beendigung des Programms verloren gehen, das sie verwaltet; – persistent, wenn sie über die Beendigung des verwaltenden Programms hinaus erhalten bleiben. Objektorientierte Programme benötigen Mechanismen zur Realisierung der Persistenz von Objekten. – Einsatz eines Datenbank-Systems ● ● ● – Objektorientiertes Datenbank-System Relationales Datenbank-System Java: Java Data Base Connectivity (JDBC) Zugriffsschicht auf Datenhaltung Java: Java Data Objects (JDO) Speicherung von Objektstrukturen in Dateien mit Senken und Iteratoren ● Objekt-Serialisierung (Object Serialization) ● Die Dateien werden als Channels benutzt: ● Zuerst schreiben in eine Sink ● Dann lesen mit Iterator 56 Objekt-Serialisierung in Java Die Klassen java.io.ObjectOutputStream und java.io.ObjectInputStream stellen Methoden bereit, um ein Geflecht von Objekten linear darzustellen (zu serialisieren) bzw. aus dieser Darstellung zu rekonstruieren. ■ Prof. U. Aßmann, Softwaretechnologie, TU Dresden ■ ► import java.io.*; Ein OutputStream entspricht dem Entwurfsmuster Sink Ein InputStream entspricht dem Entwurfsmuster Iterator Prof. U. Aßmann, Softwaretechnologie, TU Dresden ► Objekt-Serialisierung: Abspeichern Eine Klasse, die Serialisierung zulassen will, muß die (leere!) Prädikat-Schnittstelle java.io.Serializable implementieren. class ObjectOutputStream { public ObjectOutputStream (OutputStream out) throws IOException; // push Method public void writeObject (Object obj) throws IOException; } class XClass implements Serializable { private int x; public XClass (int x) { this.x = x; } } ... XClass xobj; ... FileOutputStream fs = new FileOutputStream("Xfile.dat"); ObjectOutputStream os = new ObjectOutputStream(fs); // internally realized as push for all child objects os.writeObject(xobj); ... 58 Objekt-Serialisierung: Einlesen The End import java.io.*; ► class XClass implements Serializable { private int x; public XClass (int x) { this.x = x; } } Diese Folien sind eine überarbeitete Version der Vorlesungsfolien zur Vorlesung Softwaretechnologie von © Prof. H. Hussmann, 2002. used by permission. Prof. U. Aßmann, Softwaretechnologie, TU Dresden Prof. U. Aßmann, Softwaretechnologie, TU Dresden 57 ... XClass xobj; ... FileInputStream fs = new FileInputStream("Xfile.dat"); ObjectInputStream os = new ObjectInputStream(fs); // internally realised as pull xobj = (XClass) os.readObject(); 59 60