Objektorientierte Implementierung mit Java-Datenstrukturen 1 Verfeinern von Assoziationen mit dem Java-2 Collection Framework 2 Programmieren gegen Schnittstellen 3 Auswahl von Datenstrukturen 4 Persistente Datenhaltung Softwaretechnologie 1 Objektorientierte Implementierung Verfeinern von Assoziationen mit dem Java-2 Collection Framework Softwaretechnologie, © Prof. Uwe Aßmann, Prof. Heinrich Hussmann 2 Obligatorische Literatur ► JDK Tutorial für J2SE oder J2EE, www.java.sun.com Softwaretechnologie 3 Anwendungsbeispiel für Datenstrukturen Grobes Entwurfsmodell „Bestellungsabwicklung“ (Auszug): Bestellung – kunde: String + neuePosition(b: Bestellposition) + löschePosition(pos int) +sonderpreis(pos: int, preis: int) + auftragssumme(): int + print() 1 {ordered} * Bestellposition – anzahl: String – preis: int + einzelpreis(): int + einzelpreis(p: int) + positionspreis(): int für Überladene Namen! * 1 Artikel – name: String – preis: int Softwaretechnologie + preis(): int 4 Zentrale Frage: ► Wie bilde ich einseitige Assoziationen aus UML auf Java ab? ► Antwort 1: durch Abbildung auf Arrays Softwaretechnologie 5 Testprogramm für Anwendungsbeispiel (1) public static void main (String[] args) { Artikel tisch = new Artikel("Tisch",200); Artikel stuhl = new Artikel("Stuhl",100); Artikel schrank = new Artikel("Schrank",300); Bestellung b1 = new b1.neuePosition(new b1.neuePosition(new b1.neuePosition(new b1.print(); ...} Online: Bestellung0.java Softwaretechnologie Bestellung("TUD"); Bestellposition(tisch,1)); Bestellposition(stuhl,4)); Bestellposition(schrank,2)); Bestellung fuer Kunde TUD 0. 1 x Tisch Einzelpreis: 200 Summe: 200 1. 4 x Stuhl Einzelpreis: 100 Summe: 400 2. 2 x Schrank Einzelpreis: 300 Summe: 600 Auftragssumme: 1200 6 Testprogramm für Anwendungsbeispiel (2) public static void main (String[] args) { ... b1.sonderpreis(1,50); b1.print(); } Bestellung fuer Kunde TUD 0. 1 x Tisch Einzelpreis: 200 Summe: 200 1. 4 x Stuhl Einzelpreis: 50 Summe: 200 2. 2 x Schrank Einzelpreis: 300 Summe: 600 Auftragssumme: 1000 Softwaretechnologie 7 Einfache Realisierung mit Arrays (1) class Bestellung { private String kunde; private Bestellposition[] liste; private int anzahl = 0; public Bestellung(String kunde) { this.kunde = kunde; liste = new Bestellposition[20]; } public void neuePosition (Bestellposition b) { liste[anzahl] = b; anzahl++; // was passiert bei mehr als 20 Positionen ? } public void loeschePosition (int pos) { // geht mit Arrays nicht einfach zu realisieren ! } Softwaretechnologie 8 Einfache Realisierung mit Arrays (2) public void sonderpreis (int pos, int preis) { liste[pos].einzelpreis(preis); } public int auftragssumme() { int s = 0; for(int i=0; i<anzahl; i++) s += liste[i].positionspreis(); return s; } ... } Softwaretechnologie 9 Probleme der Realisierung mit Arrays ► ► ► Dynamische Arrays ? ■ Obergrenze erweiterbar ■ Automatisches Verschieben bei Löschen Was passiert, wenn keine Ordnung benötigt wird? Kann das Array sortiert werden? ■ Viele Algorithmen laufen auf sortierten Universen wesentlich schneller als auf unsortierten (z.B. Queries in Datenbanken) Softwaretechnologie 10 Collections ► ► Probleme werden durch das Java-Collection-Framework gelöst, eine objektorientierte Datenstrukturbibliothek für Java ■ Meiste Standard-Datenstrukturen abgedeckt ■ Verwendung von Vererbung zur Strukturierung ■ Flexibel auch zur eigenen Erweiterung Basiert auf Java Generic Library (JGL) der Firma ObjectSpace ■ Erst seit Java 1.2 (Java-2) Standard . java.util. ► Zentrale Frage: Wie bilde ich einseitige Assoziationen aus UML auf Java ab? ► Antwort: Einziehen von Behälterklassen (collections) aus dem Collection-Framework ■ Flachklopfen (lowering) von Sprachkonstrukten: Wir klopfen Assoziationen zu Java-Behälterklassen flach. Softwaretechnologie 11 Flachklopfen von Assoziationen auf Behälterklassen Ersetzen von “*”-Assoziationen durch Behälterklassen Bestellung – kunde: String + neuePosition(b: Bestellposition) + löschePosition(pos int) +sonderpreis(pos: int, preis: int) + auftragssumme(): int + print() 1 Bestellung – kunde: String + neuePosition(b: Bestellposition) + löschePosition(pos int) +sonderpreis(pos: int, preis: int) + auftragssumme(): int + print() <<interface>> Collection 1 {ordered} * Bestellposition – anzahl: String – preis: int Bestellposition – anzahl: String – preis: int + einzelpreis(): int + einzelpreis(p: int) + positionspreis(): int + einzelpreis(): int + einzelpreis(p: int) + positionspreis(): int für * für 1 * * 1 Artikel – name: String – preis: int Softwaretechnologie + preis(): 1 {ordered} int Artikel – name: String – preis: int + preis(): int 12 Facetten von Behälterklassen ► Behälterklassen können anhand von verschiedenen Facetten klassifiziert werden ■ Facetten sind orthogonale Dimensionen einer Klassifikation oder eines Modells Ordnung Duplikate Sortierung Schlüssel geordnet ungeordnet mit Duplikaten ohne Duplikate sortiert unsortiert mit Schlüssel ohne Schlüssel Softwaretechnologie 13 Java Collection Framework: Struktur <<interface>> Collection Ordnung <<interface>> List Schlüssel Duplikate <<interface>> Set <<interface>> Map Sortierung <<interface>> SortedSet <<interface>> SortedMap /home/ua1/Courses/ST1/Ressourcen/jdk-1_5_0-doc/index.html Softwaretechnologie 14 Klassifikation der Schnittstellen der Datenstrukturen ► ► ► ► Collection (Kollektion): ■ Ansammlung von Datenelementen ■ Hinzufügen, Entfernen, Suchen, Durchlaufen Set (Menge): ■ Mehrfachvorkommen spielen keine Rolle ■ Reihenfolge des Einfügens spielt keine Rolle ■ SortedSet (geordnete Menge): Ordnung auf den Elementen + Sortierung List (Liste): ■ Mehrfachvorkommen werden separat abgelegt ■ Reihenfolge des Einfügens bleibt erhalten Map (Abbildung, mapping, associative array): ■ Zuordnung von Schlüsselwerten auf Eintragswerte ■ Mehrfachvorkommen bei Schlüsseln verboten, bei Einträgen erlaubt SortedMap (geordnete Abbildung): Ordnung auf den Schlüsseln + Softwaretechnologie Sortierung danach ■ 15 Schnittstelle java.util.Collection (Auszug) public interface Collection { // Queries public boolean isEmpty(); public boolean contains (Object o); public boolean equals(Object o); public int size(); // Repräsentations-Transformierer public Object[] toArray(); // Zustandsveränderer public boolean add (Object o); public boolean remove (Object o); public void clear(); ... } Softwaretechnologie 16 java.util.List (Auszug) public interface List extends Collection { public public public public public public boolean isEmpty(); boolean contains (Object o); int size(); boolean add (Object o); boolean remove (Object o); void clear(); public public public public ... Object get (int index); Object set (int index, Object element); Object remove (int index); int indexOf (Object o); } Softwaretechnologie 17 java.util.Set (Auszug) public interface Set { public public public public public public public ... public ... public boolean isEmpty(); boolean contains (Object o); int size(); boolean add (Object o); // Semantik?? boolean remove (Object o); void clear(); boolean equals (Object o); int hashCode(); Iterator iterator(); } Softwaretechnologie 18 Object - Collection - List : Beispiel o : Object Keine speziellen Operationen anwendbar "instanceOf" o : XCol XCol "implements" Collection add, remove, clear, isEmpty, contains, size "instanceOf" o : XList XList "implements" List add, remove, clear, isEmpty, contains, size, get, set, remove, indexOf Softwaretechnologie 19 Die Klasse "Object" (Wiederholung) • java.lang.Object: allgemeine Eigenschaften aller Objekte. ■ Jede Klasse ist Unterklasse von Object (“extends Object”). ■ Diese Vererbung ist implizit (d.h. man kann “extends Object” weglassen). ■ Dadurch werden Probleme mit Mehrfachvererbung vermieden. class Object { public boolean equals (Object obj); public int hashCode(); public String toString(); ... } • Jede Klasse kann die Standard-Operationen überdefinieren: – equals: Objektgleichheit (Standard: Referenzgleichheit) – hashCode: Zahlcodierung – toString: Textdarstellung, z.B. für println() Softwaretechnologie 20 Abstrakter und konkreter Datentyp Konkreter Datentyp (Implementierung) Abstrakter Datentyp (Schnittstelle) Konkretisierung: Abstraktion: ► ► ■ Instantiierbare Klassen ■ Operationen ■ Ausführbare Operationen ■ Verhalten der Operationen Theorie: ■ Datenstrukturen ■ Komplexität Praxis: ■ ► ► ■ ■ Verkettete Liste ■ Liste durch Feld Softwaretechnologie Algebraische Spezifikationen . ► Alternativen Beispiel: Theorie: ► Axiomensysteme Praxis: ■ Abstrakte Klassen ■ Interfaces Beispiel: ■ List 21 Implementierungen im Collection-Framework Vererbung (extends) <<interface>> Collection <<interface>> List Implementierung (implements) <<interface>> Set <<interface>> SortedSet ArrayList LinkedList Softwaretechnologie HashSet <<interface>> Map <<interface>> SortedMap HashMap TreeSet TreeMap 22 Beispiel: Implementierungsklasse java.util.ArrayList (Auszug) public class ArrayList implements List { public boolean add (Object o); public boolean remove (Object o); //exception! 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 ArrayList (int initialCapacity); public void ensureCapacity (int minCapacity); ... } Softwaretechnologie 23 Objektorientierte Implementierung 2 Programmieren gegen Schnittstellen "Der Aufrufer programmiert gegen die Schnittstelle, er befindet sich sozusagen im luftleeren Raum." Siedersleben/Denert, Wie baut man Informationssysteme, Informatik-Spektrum, August 2000 Softwaretechnologie, © Prof. Uwe Aßmann, Prof. Heinrich Hussmann 24 Anwendungsbeispiel mit ArrayList (1) 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(); } public void neuePosition (Bestellposition b) { liste.add(b); } public void loeschePosition (int pos) { liste.remove(pos); } ... Softwaretechnologie 25 Anwendungsbeispiel mit ArrayList (falsch!) ... public void sonderpreis (int pos, int preis) { liste.get(pos).einzelpreis(preis); } ... ► Compilermeldung: „Method einzelpreis(int) not found in class java.lang.Object.“ ? liste.get(pos).einzelpreis(preis); ArrayList Object definiert auf Bestellposition Spezialisierung von Object auf Bestellposition? Softwaretechnologie 26 Programmieren gegen Schnittstellen mit Typanpassungen * Object Bestellung – kunde: String – anzahl: int 1 java.util.ArrayList add(Object o) liste get(pos: int): Object ... * Zusicherung: Alle von einem Bestellung-Objekt über die liste-Assoziation erreichbaren Objekte sind aus der Klasse Bestellposition. 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) Softwaretechnologie 27 Anwendungsbeispiel mit ArrayList (2) public void sonderpreis (int pos, int preis) { ((Bestellposition)liste.get(pos)).einzelpreis(preis); } public int auftragssumme() { int s = 0; for(int i=0; i<liste.size(); i++) s += ((Bestellposition)liste.get(i)).positionspreis(); return s; } } 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 Softwaretechnologie 28 Iterator-Konzept ► Aufzählen der in einem “Behälter” befindlichen Elemente ■ Keine Aussage über die Reihenfolge! ■ Interface java.util.Iterator interface Iterator { public boolean hasNext(); public Object next(); public void remove(); } Verwendungsbeispiel: ► Iterator i = ...; while (i.hasNext()) { doSomeThing(i.next()); } Erzeugung eines Iterators für eine beliebige Kollektion (deklariert in java.util.Collection): public Iterator iterator(); Softwaretechnologie 29 Anwendungsbeispiel mit Iteratoren import java.util.Iterator; ... class Bestellung { private String kunde; private ArrayList liste; ... public int auftragssumme() { Iterator i = liste.iterator(); int s = 0; while (i.hasNext()) s += ((Bestellposition)i.next()).positionspreis(); return s; } ... } Online: Bestellung2.java Softwaretechnologie 30 java.util.LinkedList (Auszug) 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 Softwaretechnologie 31 Programmieren gegen Schnittstellen -- Polymorphe Container class Bestellung { private String kunde; private List liste; ! List ist ein Interface, keine Klasse ! ... // Konstruktor sh. nächste Folien public void neuePosition (Bestellposition b) { liste.add(b); } public void loeschePosition (int pos) { liste.remove(pos); } public void sonderpreis (int pos, int preis) { ((Bestellposition)liste.get(pos)).einzelpreis(preis); } Softwaretechnologie 32 Wechsel der Datenstruktur • ArrayList: class Bestellung { private String kunde; private List liste; public Bestellung(String kunde) { this.kunde = kunde; this.liste = new ArrayList(); } ... ! List ist ein Interface, keine Klasse ! • LinkedList: class Bestellung { private String kunde; private List liste; public Bestellung(String kunde) { this.kunde = kunde; this.liste = new LinkedList(); } ... Softwaretechnologie Code muß bei Wechsel der Datenstruktur nur an einer Stelle (Konstruktor) geändert werden ! 33 Standardalgorithmen in java.util.Collections 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) ... } • Algorithmen arbeiten mit beliebigen Klassen, die das Collectionbzw. List-Interface implementieren. • Bei manchen Operationen ist Ordnung auf Elementen vorausgesetzt. • Statische Operationen: Aufruf z.B. Collections.sort(...) Softwaretechnologie 34 Ordnung auf Elementen: java.lang.Comparable public interface Comparable { public int compareTo (Object o); } Resultat kleiner/gleich/größer 0: genau dann wenn "this" kleiner/gleich/größer als Objekt o Standarddatentypen (z.B. String) implementieren Comparable Softwaretechnologie 35 Prädikat-Schnittstellen (...able Schnittstellen) ► Schnittstellen, die die Eigenschaft einer Klasse ausdrücken, werden oft mit dem Suffix “able” benannt: ■ ■ ■ Iterable Clonable Serializable Softwaretechnologie 36 Objektorientierte Implementierung mit Java-Datenstrukturen 3 Auswahl von Datenstrukturen Softwaretechnologie, © Prof. Uwe Aßmann, Prof. Heinrich Hussmann 37 Weitere Implementierungen Vererbung (extends) <<interface>> Collection <<interface>> List Implementierung (implements) <<interface>> Set <<interface>> Map <<interface>> SortedSet <<interface>> SortedMap ArrayList LinkedList Vector Softwaretechnologie HashSet HashMap TreeSet Hashtable TreeMap 38 Welche Listen-Implementierung soll man wählen? Gemessener relativer Aufwand für Operationen auf Listen: (aus Eckel, Thinking in Java, 2nd ed., 2000) Typ Lesen Iteration Einfügen Entfernen array 1430 3850 --ArrayList 3070 12200 500 46850 LinkedList 16320 9110 110 60 Vector 4890 16250 550 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 Softwaretechnologie 39 Collection Framework (Überblick) Vererbung (extends) <<interface>> Collection <<interface>> List Implementierung (implements) <<interface>> Set <<interface>> SortedSet <<interface>> Map <<interface>> SortedMap ArrayList LinkedList HashSet HashMap TreeSet Softwaretechnologie TreeMap 40 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(); } Softwaretechnologie 41 Anwendungsbeispiel für Set Warengruppe – name: String – lagerplatz: String + add (a: Artikel) + anzahl(): int 1 * Artikel – name: String – preis: int + preis(): int Softwaretechnologie 42 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 !) Softwaretechnologie 43 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 } Softwaretechnologie 44 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 Softwaretechnologie 45 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 Moebel Tisch(200) Tisch(200) Schrank(300) Stuhl(100) Online: Warengruppe0.java Softwaretechnologie 46 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 Moebel Schrank(300) Tisch(200) Stuhl(100) Es wurde zweifach dasselbe Tisch-Objekt übergeben ! Softwaretechnologie 47 Delegation vs. Vererbung class Warengruppe { … private Set inhalt; } Delegation public Warengruppe (…) { … this.inhalt = new HashSet(); } public void add (Artikel a) { inhalt.add(a); } … class Warengruppe extends HashSet { … Vererbung public Warengruppe (…) { super(); … } … // keine explizite add-Operation nötig ! } Warengruppe2.java Softwaretechnologie 48 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(); ... } Softwaretechnologie 49 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 Softwaretechnologie 50 java.util.TreeSet ► java.util.TreeSet implementiert ein geordnete Menge und benötigt Comparable ► 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 … { … } Softwaretechnologie 51 Anwendungsbeispiel mit TreeSet ► Artikel muss 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 Softwaretechnologie 52 HashSet oder TreeSet? ► Gemessener relativer Aufwand für Operationen auf Mengen: (aus Eckel, Thinking in Java, 2nd ed., 2000) Typ HashSet TreeSet ► Enthalten 106,5 177,4 Iteration 39,39 40,04 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 Softwaretechnologie 53 Collection Framework (Überblick) Vererbung (extends) <<interface>> Collection <<interface>> List Implementierung (implements) <<interface>> Set <<interface>> SortedSet <<interface>> Map <<interface>> SortedMap ArrayList LinkedList HashSet HashMap TreeSet Softwaretechnologie TreeMap 54 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(); ... } Eine Map ist ein „assoziativer Speicher“ (associative array) Softwaretechnologie 55 Anwendungsbeispiel Katalog – name: String + put (code: String, a: Artikel) + get (code: String): Artikel + anzahl(): int code: String * 1 Artikel – name: String – preis: int HashMap ist eine sehr günstige Umsetzung für qualifizierte Assoziationen: Der Qualifikator bildet den Schlüssel; die Zielobjeke den Wert + preis(): int Softwaretechnologie 56 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 Softwaretechnologie 57 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 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). Softwaretechnologie 58 Prinzip der Hashtabelle ► Typischerweise wird der Schlüssel (key) vor dem Einstechen auf einen Zahlenbereich modulo der Kapazität der Hashtabelle abgebildet, d.h., der Schlüssel wird auf die Hashtabelle “normiert” (hash code) hashtab Object 0 hashCode(): int key: Object key.hashCode() value: Object value: Object Effekt von hashtab.put(key,value) Softwaretechnologie capacity 59 Kollision beim Einstechen ► Bei nicht eindeutigen Schlüsseln, oder auch durch die Normierung, werden Einträge doppelt “adressiert” (Kollision) 0 key1: Object value1: Object key2: Object key1.hashCode() value?: Object = key2.hashCode() value2: Object Verfahren zur Kollisionsauflösung: – Überlauflisten – Überlauf in der Hashtabelle Softwaretechnologie capacity 60 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 (Nutzung der Collection-Bibliothek) Ggf. Experimente (experimentelle Prototypen) Anpassung an vorgefertigte Lösung Softwaretechnologie Entwicklung einer neuartigen Lösung 61 Suche nach vorgefertigten Lösungen (Collection-Klassen der Bibliothek) Collection Map Einfügen eines Elements Entfernen eines Elements Aufzählen aller Elemente "ist enthalten"-Abfrage dynamisch erweiterbar Einfügereihenfolge relevant? ja 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 List Abfrage an i-ter Position Set Sortierung relevant? Ersetzen an i-ter Position SortedSet kleinstes/größtes Element Entfernen an i-ter Position Elemente "über"/"unter" x Softwaretechnologie 62 Beispiel: Realisierung von Assoziationen A * assoc B Datenstruktur im A-Objekt für B-Referenzen Anforderung 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 Realisierung 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 Softwaretechnologie 63 Realisierung von ungeordneten 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(); } Softwaretechnologie 64 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) Softwaretechnologie 65 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; } ... Softwaretechnologie 66 Objektorientierte Implementierung mit Java-Datenstrukturen 4 Persistente Datenhaltung Art is long, and Time is fleeting. H. W. Longfellow Softwaretechnologie, © Prof. Uwe Aßmann, Prof. Heinrich Hussmann 67 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) Softwaretechnologie 68 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; } Softwaretechnologie 69 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); ... Softwaretechnologie 70 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(); Softwaretechnologie 71 The End ► Diese Folien sind eine überarbeitete Version der Vorlesungsfolien zur Vorlesung Softwaretechnologie von © Prof. H. Hussmann, 2002. used by permission. Softwaretechnologie 72