Abstrakte Datentypen und Java hEHUEOLFN 5HDOLVLHUXQJYRQ$'7→ NRQNUHWH'DWHQW\SHQ %HLVSLHO5DWLRQDOH=DKO 3DUDPHWULVLHUWH'DWHQW\SHQ %HLVSLHO)HOG6RUWLHUWHV)HOG 6FKQLWWVWHOOHQNRQ]HSW :LFKWLJH'DWHQW\SHQLQ-DYD Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 1 Motivation ADT in Programmiersprachen Konzept der Kapselung Verbergen der internen Repräsentation gleiche Verwendung trotz unterschiedlicher Implementierung Vorteile Stabilität gegenüber Änderungen Auswahl einer geeigneten Implementierungsvariante Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 2 1 Umsetzung ADT in Java Typen → Klassen, Schnittstellen Funktionen → Methoden Klassen als konkrete Implementierung Sammlungen von Daten und Methoden, die auf Daten operieren beschreiben Eigenschaften von Objekten Schnittstellen Sammlung von Konstanten und abstrakten Methoden ohne Implementierung Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 3 Vererbung Klasse erbt von Klasse: classA extends classB erben der Daten und Methodenimplementierungen Schnittstelle erbt von Schnittstelle: interfA extends interfA erben der Konstanten und Methodensignaturen Klasse implementiert Schnittstelle: classA implements interfA erben der Methodensignaturen + Bereitstellung einer Implementierung Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 4 2 Beispiel: Rationale Zahlen in Java Implementierung des ATD als Klasse public class RatZahl { private int zaehler = 0; private int nenner = 1; ... } Konstruktoren public RatZahl () {} public RatZahl (int z, int n) { zaehler = z; nenner = n; kuerzen (); } Selektoren public int zaehler () { return this.zaehler; } public int nenner () { return this.nenner; } Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 5 Beispiel: Rationale Zahlen Implementierung der Funktion add: RatZahl × RatZahl → RatZahl Varianten static RatZahl add (RatZahl z1, RatZahl z2) void add (RatZahl z) RatZahl add (RatZahl z) üblicherweise public RatZahl addiere (RatZahl n) { int nnenn = kgv (this.nenner, n.nenner()); int nzaeh1 = nnenn / this.nenner * zaehler; int nzaeh2 = nnenn / n.nenner() * n.zaehler(); return new RatZahl (nzaeh1 + nzaeh2, nnenn); } Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 6 3 Rationale Zahlen: Nutzung Erzeugen RatZahl r1 = new RatZahl (1, 3); RatZahl r2 = new RatZahl (3, 4); Rechnen RatZahl res = r1.add (r2); Ausgeben System.out.println ("Ergebnis = " + res); Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 7 Parametrisierte Datentypen in Java Kollektionen Klassen zur Verwaltung einer Mehrzahl gleich strukturierter Objekte Ausprägungen: Felder, Listen, Stacks, Sets, ... Beispiel: Realisierung als Feldtypen int feld[] Probleme: Nutzung mit verschiedenen Elementtypen: Feld von intWerten, von Strings, von rationalen Zahlen ... umständliche Handhabung: Anfügen, Einfügen an Position 0, ... fehlende Semantik Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 8 4 Realisierungsvarianten Programmiersprachen mit gemeinsamer Wurzelklasse Object: Elementtyp = Wurzelklasse universell verwendbar Problem: Typunsicherheit Beispiel: Java, Smalltalk Programmiersprachen ohne gemeinsame Wurzelklasse Schablonen oder Templates Instantiierung mit konkreten Elementtyp typsicher Generierung spezifischen Codes durch Compiler Beispiel: C++ Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 9 Beispiel: Feld von Objekten Implementierung auf Basis des Java-Array-Typs public class ObjFeld { private Object daten[] = null; public ObjFeld () {} public int laenge () { return (daten == null ? 0 : daten.length); } public Object element (int idx) { if (daten == null || idx < 0 || idx >= laenge ()) throw new ArrayIndexOutOfBoundsException (); else return daten[idx]; } ... } Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 10 5 Beispiel: Feld von Objekten (2) Einfügen von Elementen public void einfuegen (int pos, Object o) { int i, num = laenge (); if (pos == -1) pos = num; Object ndaten[] = new Object[num + 1]; for (i = 0; i < pos; i++) ndaten[i] = daten[i]; ndaten[i++] = o; for (; i < num + 1; i++) ndaten[i] = daten[i - 1]; daten = ndaten; } Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 11 Feld von rationalen Zahlen Einfügen von Objekten der Klasse RatZahl ObjFeld feld = new ObjFeld (); feld.einfuegen (-1, new RatZahl (1, 3)); feld.einfuegen (-1, new RatZahl (2, 3)); Zugriff auf Elemente erfordert explizite Typkonvertierung (type cast) RatZahl rz = (RatZahl) feld.element (0); Test auf Zugehörigkeit zu einer Klasse Object o = feld.element (0); if (o instanceof RatZahl) { RatZahl rz = (RatZahl) o; ... } Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 12 6 Erweiterung: Sortiertes Feld SortFeld: Erweiterung von ObjFeld um Sortierung Zugriff über Index in geordneter Reihenfolge (0: kleinstes Element, laenge-1: größtes Element) Sicherstellung der Reihenfolge Einfügen eines neuen Elementes an der richtigen Position Anhängen des Elementes und anschließendes Sortieren Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 13 Problem: „Vergleichbare“ Objekte notwendig: Ordnung über Elementtypen → Vergleichsoperator < Problem: nicht definiert für java.lang.Object Realisierungsmöglichkeiten: neue Basisklasse ComparableObject mit definiertem Vergleichsoperator y Problem: fehlende Mehrfachvererbung in Java Verwendung von Schnittstellen Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 14 7 Schnittstellenkonzept Schnittstelle (interface) interface Speicherbar { void speichern (OutputStream out); void laden (InputStream in); } Sammlung abstrakter Methoden keine Methodenimplementierung werden von Klassen bereitgestellt keine Instantiierung möglich aber: Objektreferenzen können vom Typ einer Schnittstelle sein Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 15 Sortierung rationaler Zahlen java.lang.Comparable: vordefinierte Schnittstelle für „vergleichbare“ Objekte interface Comparable { int compareTo (Object o); } liefert -1 für kleiner, 0 für gleich, 1 für größer u.a. implementiert von String, ... Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 16 8 Vergleich rationaler Zahlen Klasse RatZahl implementiert Schnittstelle java.lang.Comparable public class RatZahl implements Comparable { ... public int compareTo (Object o) { RatZahl z = (RatZahl) o; double r1 = rational (), r2 = z.rational (); if (r1 < r2) return -1; else if (r1 > r2) return 1; else return 0; } } Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 17 Implementierung von SortFeld interne Repräsentation Comparable daten[] Verwaltung „vergleichbarer“ Objekte: Feld mit Referenzen auf Objekte, die Schnittstelle Comparable implementieren Zugriff auf Vergleichsoperator compareTo Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 18 9 Implementierung von SortFeld Einfügeoperation public void einfuegen (Comparable o) { int i = 0, num = laenge (); Comparable ndaten[] = new Comparable[num + 1]; while (i < num && daten[i].compareTo(o) < 0) { ndaten[i] = daten[i]; i++; } ndaten[i++] = o; while (i < num + 1) { ndaten[i] = daten[i - 1]; i++; } daten = ndaten; } Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 19 Navigation über Kollektionen Navigation = „Durchwandern“ einer Kollektion abhängig von der Implementierung Beispiel: Feld for (int i = 0; i < feld.laenge (); i++) Object o = feld.element (i); für verkettete Listen: anderes Verfahren notwendig Iterator: Objekt zum Iterieren über Kollektionen unabhängig von interner Realisierung einheitliche Behandlung Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 20 10 Iterator-Konzept Ite ra tor F eld Ite ra tor Lis te Ite ra tor Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 21 Iterator-Konzept Iterator-Schnittstelle java.util.Iterator Ende der Kollektion erreicht ? boolean hasNext () aktuelles Element liefern und internen Zeiger weitersetzen Object next () aktuelle Element löschen void remove () Beispiel: Iterator i = feld.iterator (); while (i.hasNext ()) Object o = i.next (); Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 22 11 Iterator für Felder Definition einer speziellen Klasse FeldIterator class FeldIterator implements java.util.Iterator { Feld feld; int pos = 0; FeldIterator (Feld f) { feld = f; } public boolean hasNext () { return pos < feld.laenge (); } public Object next () { if (! hasNext ()) throw new java.util.NoSuchElementException (); return feld.element(pos++); } } Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 23 Iterator für Felder Erzeugung eines Iterators public class Feld { ... Iterator iterator () { return new FeldIterator (this); } } Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 24 12 Weitere wichtige Schnittstellen java.lang.Serializable Speicherung und Wiederherstellen von Objekten inkl. ihres Zustandes und ihrer Beziehungen Verwendung mit Objekt-Streams keine zusätzlichen Methoden notwendig java.lang.Clonable Kopieren von Objekten: Erzeugung einer neuen Instanz mit gleichen Eigenschaften Methode: Object clone () java.awt.event.ActionListener EventListener für AWT und Swing Verarbeitung von Ereignissen (z.B. Betätigen eines Buttons) Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 25 Java-Kollektionen Java Collection Framework Bereitstellung wichtiger Kollektionen (Listen, Mengen, Verzeichnisse) mit unterschiedlicher Implementierung Navigation mittels Iteratoren Implementierung häufig benutzter Algorithmen (Suchen, Sortieren, kleines/größtes Element, ...) Basis java.util.Collection y Schnittstelle für alle Kollektionsklassen Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 26 13 Schnittstelle java.util.Collection Größe der Kollektion int size () boolean isEmpty () Suchen von Elementen boolean contains (Object o) boolean containsAll (Collection c) Navigation Iterator iterator () Hinzufügen/Entfernen boolean boolean boolean boolean Gunter Saake Kai-Uwe Sattler add (Object o) remove (Object o) addAll (Collection c) removeAll (Collection c) Algorithmen & Datenstrukturen 27 Ausgewählte Kollektionen java.util.List Repräsentation von Listen (geordnet nach Einfügereihenfolge, Duplikate zulässig) java.util.Set Repräsentation von Mengen (ungeordnet/geordnet, ohne Duplikate) java.util.Map Verzeichnis (Dictionary) von Objekten (SchlüsselWert-Paare) für schnellen Zugriff über Schlüssel Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 28 14 Listen mit java.util.List java.util.List: Schnittstelle für Listen Zugriff über Position Object get (int idx) Object set (int idx, Object o) void add (int idx, Object o) Object remove (int idx) Bestimmen der Position eines Objektes int indexOf (Object o) konkrete Implementierungen verkettete Liste: LinkedList Feld: ArrayList Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 29 Struktur des Collection Framework A b stractC ollection C o llectio n L ist A b stractList A b stractS et A rrayList A b stractS equen tialList Linked List Gunter Saake Kai-Uwe Sattler Set H ashS et So rtedSet Tre eS et Klasse extends S c h n ittstelle implements Algorithmen & Datenstrukturen 30 15 Algorithmen für Kollektionen Klasse java.util.Collections Sortieren von Listen static void sort (List list) Suchen in Listen static void binarySearch (List list, Object key) Umkehren static void reverse (List list) zufällige Ordnung static void shuffle (List list) kleinstes/größtes Element static Object min (Collection col) static Object max (Collection col) Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 31 Anwendungsbeispiel // Liste erzeugen und Objekte einfügen LinkedList list = new LinkedList (); list.add (new RatZahl (1, 3)); list.add (new RatZahl (1, 4)) list.add (new RatZahl (1, 5)); // Sortieren Collections.sort (list); // Ausgeben Iterator i = list.iterator (); while (i.hasNext ()) System.out.println (i.next ()); Gunter Saake Kai-Uwe Sattler Algorithmen & Datenstrukturen 32 16