5. Objektorientierte Implementierung mit Java-Datenstrukturen 5.1 5.2 5.3 5.4 Java-2 Collection Framework Generisches Programmieren Auswahl von Datenstrukturen Persistente Datenhaltung Technische Universität Dresden Prof. Hußmann Softwaretechnologie 5. Objektorientierte Implementierung mit Java-Datenstrukturen 5.3 Auswahl von Datenstrukturen Technische Universität Dresden Prof. Hußmann Seite 1 Softwaretechnologie "Alte" Datenstrukturen (aus Java 1.0) <<interface>> Vererbung (extends) Collection Implementierung (implements) <<interface>> <<interface>> <<interface>> List Set Map <<interface>> <<interface>> SortedSet SortedMap ArrayList HashSet LinkedList Vector TreeSet Technische Universität Dresden Prof. Hußmann HashMap Hashtable TreeMap Softwaretechnologie Welche Listen-Implementierung? • Gemessener relativer Aufwand für Operationen auf Listen: (aus Eckel, Thinking in Java, 2nd ed., 2000) Typ array ArrayList LinkedList Vector Lesen 1430 3070 16320 4890 Iteration 3850 12200 9110 16250 Einfügen -500 110 550 Entfernen -46850 60 46850 • 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 Technische Universität Dresden Prof. Hußmann Seite 2 Softwaretechnologie Collection Framework (Überblick) <<interface>> Vererbung (extends) Collection Implementierung (implements) <<interface>> <<interface>> <<interface>> List Set Map <<interface>> <<interface>> SortedSet SortedMap ArrayList LinkedList HashSet HashMap TreeSet Technische Universität Dresden Prof. Hußmann TreeMap Softwaretechnologie java.util.Set (Auszug) public interface Set { public public public public public public ... public public ... public boolean add (Object o); boolean remove (Object o); void clear(); boolean isEmpty(); boolean contains (Object o); int size(); boolean equals (Object o); int hashCode(); Iterator iterator(); } Technische Universität Dresden Prof. Hußmann Seite 3 Softwaretechnologie Anwendungsbeispiel für Set Warengruppe – name: String – lagerplatz: String + add (a: Artikel) + anzahl(): int 1 * Artikel – name: String – preis: int + preis(): int Technische Universität Dresden Prof. Hußmann Softwaretechnologie java.util.HashSet (Auszug) public class HashSet implements Set ... { public HashSet (int initialCapacity, float loadFactor); ... 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 boolean equals (Object o); public int hashCode(); ... public Iterator iterator(); } (Anmerkung: Erläuterung von Hashfunktionen folgt etwas später !) Technische Universität Dresden Prof. Hußmann Seite 4 Softwaretechnologie Anwendungsbeispiel mit HashSet 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 Technische Universität Dresden Prof. Hußmann Softwaretechnologie Wann sind Objekte gleich? (1) • 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 Technische Universität Dresden Prof. Hußmann Seite 5 Softwaretechnologie Wann sind Objekte gleich? (2) 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: Warengruppe Warengruppe Moebel Moebel Tisch(200) Tisch(200) Tisch(200) Tisch(200) Schrank(300) Schrank(300) Stuhl(100) Stuhl(100) Online: Warengruppe0.java Technische Universität Dresden Prof. Hußmann Softwaretechnologie Wann sind Objekte gleich? (3) public static void main (String[] args) { Artikel tisch = new Artikel("Tisch",200); Artikel stuhl = new Artikel("Stuhl",100); Artikel schrank = new Artikel("Schrank",300); Warengruppe w2 = new Warengruppe("Moebel","L2"); w2.add(tisch); w2.add(stuhl); w2.add(schrank); w2.add(tisch); System.out.println(w1); } Systemausgabe: Warengruppe Warengruppe Moebel Moebel Schrank(300) Schrank(300) Tisch(200) Tisch(200) Stuhl(100) Stuhl(100) Es wurde zweifach dasselbe Tisch-Objekt übergeben ! Technische Universität Dresden Prof. Hußmann Seite 6 Softwaretechnologie Delegation vs. Vererbung class class Warengruppe Warengruppe {{ …… private private Set Set inhalt; inhalt; Delegation public public Warengruppe Warengruppe (…) (…) {{ …… this.inhalt this.inhalt == new new HashSet(); HashSet(); }} public public void void add add (Artikel (Artikel a) a) {{ inhalt.add(a); inhalt.add(a); }} …… }} class Warengruppe extends HashSet { … Vererbung public Warengruppe (…) { super(); … } … // keine explizite add-Operation ! } Warengruppe2.java Technische Universität Dresden Prof. Hußmann Softwaretechnologie java.util.SortedSet (Auszug) public interface SortedSet extends Set { public public public public public public ... public public public ... public public boolean add (Object o); boolean remove (Object o); void clear(); boolean isEmpty(); boolean contains (Object o); int size(); boolean equals (Object o); int hashCode(); Iterator iterator(); Object first(); Object last(); ... } Technische Universität Dresden Prof. Hußmann Seite 7 Softwaretechnologie Ordnung auf Elementen: java.lang.Comparable public interface Comparable { public int compareTo (Object o); } Resultat kleiner/gleich/größer 0: "this" kleiner/gleich/größer als Objekt o Standarddatentypen (z.B. String) implementieren Comparable Technische Universität Dresden Prof. Hußmann Softwaretechnologie java.util.TreeSet • Modifikation der Klasse Warengruppe: class Warengruppe { private Set inhalt; public Warengruppe (…) { … this.inhalt = new TreeSet(); } … } • Systemreaktion: Exception in thread "main" java.lang.ClassCastException: Artikel at java.util.TreeMap.compare(TreeMap.java, Compiled Code) • java.util.TreeSet: public class TreeSet … implements SortedSet … { … } Technische Universität Dresden Prof. Hußmann Seite 8 Softwaretechnologie Anwendungsbeispiel mit TreeSet • Modifikation der Klasse „Artikel“: class class Artikel Artikel implements implements Comparable Comparable {{ ... ... public public int int compareTo compareTo (Object (Object o) o) {{ return return name.compareTo(((Artikel)o).name); name.compareTo(((Artikel)o).name); }} }} Systemausgabe: Warengruppe Warengruppe Moebel Moebel Schrank(300) Schrank(300) Stuhl(100) Stuhl(100) Tisch(200) Tisch(200) Online: Warengruppe3.java Technische Universität Dresden Prof. Hußmann Softwaretechnologie HashSet oder TreeSet? • Gemessener relativer Aufwand für Operationen auf Mengen: (aus Eckel, Thinking in Java, 2nd ed., 2000) Typ HashSet TreeSet Einfügen 36,14 150,6 Enthalten 106,5 177,4 Iteration 39,39 40,04 • Stärken von HashSet: – in allen Fällen schneller ! • Stärken von TreeSet: – erlaubt Operationen für sortierte Mengen Technische Universität Dresden Prof. Hußmann Seite 9 Softwaretechnologie Collection Framework (Überblick) <<interface>> Vererbung (extends) Collection Implementierung (implements) <<interface>> <<interface>> <<interface>> List Set Map <<interface>> <<interface>> SortedSet SortedMap ArrayList LinkedList HashSet TreeSet Technische Universität Dresden Prof. Hußmann HashMap TreeMap Softwaretechnologie java.util.Map (Auszug) public interface Map { ... public boolean containsKey (Object key); public boolean containsValue (Object value); public Object get (Object key); public Object put (Object key, Object value); public Object remove (Object key); public int size(); public Set keySet(); public Collection values(); ... } „Assoziativer Speicher“ Technische Universität Dresden Prof. Hußmann Seite 10 Softwaretechnologie Anwendungsbeispiel Katalog – name: String + put (code: String, a: Artikel) + get (code: String): Artikel + anzahl(): int code: String HashMap ist eine sehr günstige Umsetzung für qualifizierte Assoziationen * 1 Artikel – name: String – preis: int + preis(): int Technische Universität Dresden Prof. Hußmann Softwaretechnologie Anwendungsbeispiel mit HashMap 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 Technische Universität Dresden Prof. Hußmann Seite 11 Softwaretechnologie Testprogramm für Anwendungsbeispiel 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); } Katalog k = new Katalog("Katalog1"); Systemausgabe: k.put("M01",tisch); Katalog Katalog Katalog1 Katalog1 k.put("M02",stuhl); M03 M03 -> -> Schrank(300) Schrank(300) M02 -> Stuhl(100) k.put("M03",schrank); M02 -> Stuhl(100) M01 -> Tisch(200) M01 -> Tisch(200) System.out.println(k); Katalog Katalog Katalog1 Katalog1 k.put("M03",regal); M03 M03 -> -> Regal(200) Regal(200) System.out.println(k); M02 -> Stuhl(100) M02 -> Stuhl(100) M01 -> Tisch(200) M01 -> Tisch(200) put(...) put(...)überschreibt überschreibtvorhandenen vorhandenenEintrag Eintrag(Ergebnis (Ergebnis==vorhandener vorhandenerEintrag). Eintrag). Ordnung Ordnungauf aufden denSchlüsseln: Schlüsseln:SortedMap SortedMap(Implementierung (Implementierungz.B.TreeMap). z.B.TreeMap). Technische Universität Dresden Prof. Hußmann Softwaretechnologie Prinzip der Hashtabelle hashtab 0 Object hashCode(): int key: Object key.hashCode() value: Object value: Object Effekt Effekt von von hashtab.put(key,value) hashtab.put(key,value) capacity Technische Universität Dresden Prof. Hußmann Seite 12 Softwaretechnologie Kollision 0 key1: Object value1: Object key2: Object key1.hashCode() = key2.hashCode() value?: Object value2: Object Verfahren zur Kollisionsauflösung: – Überlauflisten – Überlauf in der Hashtabelle Technische Universität Dresden capacity Prof. Hußmann Softwaretechnologie Vorgehensweise beim Datenstruktur-Entwurf Identifikation der Anforderungen an die Datenstruktur: Funktionalität, häufig benutzte Operationen Abstraktion auf die wesentlichen Eigenschaften Suche nach vorgefertigten Lösungen Ggf. Experimente (experimentelle Prototypen) Anpassung an vorgefertigte Lösung Technische Universität Dresden Entwicklung einer neuartigen Lösung Prof. Hußmann Seite 13 Softwaretechnologie Suche nach vorgefertigten Lösungen Collection Map Einfügen eines Elements Entfernen eines Elements Aufzählen aller Elemente "ist enthalten"-Abfrage dynamisch erweiterbar 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 Abfrage an i-ter Position Ersetzen an i-ter Position Entfernen an i-ter Position Technische Universität Dresden Sortierung relevant? SortedSet kleinstes/größtes Element Elemente "über"/"unter" x Prof. Hußmann Softwaretechnologie Beispiel: Realisierung von Assoziationen A * B assoc Datenstruktur im A-Objekt für B-Referenzen Anforderung Abstraktion 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 1) Einfügen (ohne Reihenfolge) 2) Entfernen (ohne Reihenfolge) 3) Aufzählen aller Elemente 4) "ist enthalten"-Abfrage 5) Maximalanzahl der Elemente unbekannt; dynamisch erweiterbar Set Technische Universität Dresden Prof. Hußmann Seite 14 Softwaretechnologie Realisierung von Assoziationen mit Set A assoc * B class A { private Set assoc; ... public void addAssoc (B b) { assoc.add(b); } public boolean testAssoc (B b) { return assoc.contains(b); } public A { ... assoc = new HashSet(); } Technische Universität Dresden Prof. Hußmann Softwaretechnologie Beispiel: Raumverwaltung static Besprechungsraum freienRaumSuchen (int groesse, Hour beginn, int dauer) • 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 » 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) Technische Universität Dresden Prof. Hußmann Seite 15 Softwaretechnologie Raumverwaltung: Freien Raum suchen class Raumverwaltung { private static SortedSet vorhandeneRaeume = new TreeSet(); // Vorhandene Raeume, aufsteigend nach Groesse sortiert 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; } ... } Technische Universität Dresden Prof. Hußmann Softwaretechnologie 5. Objektorientierte Implementierung mit Java-Datenstrukturen 5.4 Persistente Datenhaltung Art Artisislong, long,and andTime Timeisisfleeting. fleeting. H. H.W. W.Longfellow Longfellow Technische Universität Dresden Prof. Hußmann Seite 16 Softwaretechnologie Temporäre und persistente Daten • 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. • Möglichkeiten zur Realisierung von Objekt-Persistenz: – 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 » Objekt-Serialisierung (Object Serialization) Technische Universität Dresden Prof. Hußmann Softwaretechnologie 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. • Eine Klasse, die Serialisierung zulassen will, muß die (leere!) Schnittstelle java.io.Serializable implementieren. class ObjectOutputStream { public ObjectOutputStream (OutputStream out) throws IOException; public void writeObject (Object obj) throws IOException; } Technische Universität Dresden Prof. Hußmann Seite 17 Softwaretechnologie Objekt-Serialisierung: Abspeichern import java.io.*; 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); os.writeObject(xobj); ... Technische Universität Dresden Prof. Hußmann Softwaretechnologie Objekt-Serialisierung: Einlesen import java.io.*; class XClass implements Serializable { private int x; public XClass (int x) { this.x = x; } } ... XClass xobj; ... FileInputStream fs = new FileInputStream("Xfile.dat"); ObjectInputStream os = new ObjectInputStream(fs); xobj = (XClass) os.readObject(); Technische Universität Dresden Prof. Hußmann Seite 18 Softwaretechnologie