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