Seite 1

Werbung
4.1 Eigenschaften „aller Objekte“
• allgemeine Eigenschaften aller Objekte in
java.lang.Object:
Kapitel 4: Datenstrukturen verstehen
– Jede Klasse ist implizit Unterklasse von Object
(“extends Object”),
d.h. man kann “extends Object” weglassen.
4.1 Eigenschaften „aller Objekte“
4.2 Implementierung von Datenstrukturen
4.3 Algorithmen auf Datenstrukturen
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Objektoiertierte Programmierung
– Probleme mit Mehrfachvererbung werden vermieden.
– auf alle Objekte anwendbare Methoden erlauben:
Objekte zu vergleichen
Objekte eindeutig zu identifizieren
Objekte zu drucken
Zugriff auf Objekte zu synchronisieren (-> später!)
K4 - 1
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Eigenschaften aus Klasse „Object“
• Vergleich mit Operation == :
– Referenzgleichheit, d.h. physische Identität der Objekte
– Typischer Fehler: Stringvergleich mit "=="
• Vergleich mit o.equals():
– deklariert in java.lang.Object
– redefiniert in vielen Bibliotheksklassen
» z.B. in java.lang.String
– für selbstdefinierte Klassen
» Standardbedeutung „Referenzgleichheit“
» bei Bedarf selbst redefinieren !
• Jede Klasse kann die Standard-Operationen redefinieren:
– equals(): Objektgleichheit (Standard: Referenzgleichheit)
– hashCode(): Zahlcodierung
(bei Verwendung z.B. in HashSet die Operation redefinieren!)
– toString(): Textdarstellung, z.B. für println()
Objektoiertierte Programmierung
K4 - 2
Wann sind Objekte gleich? (1)
class Object {
public boolean equals (Object obj);
public int hashCode();
public String toString(); ...
}
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Objektoiertierte Programmierung
K4 - 3
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Wann sind Objekte gleich? (2)
Objektoiertierte Programmierung
K4 - 4
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);
public static void main (String[] args) {
Set s = new HashSet();
s.add(new Artikel("Tisch",200)); //ein Artikel
s.add(new Artikel("Stuhl",100));
s.add(new Artikel("Schrank",300));
s.add(new Artikel("Tisch",200)); //ein aehnlicher
System.out.println(s);
}
}
Systemausgabe:
Set w2 = new HashSet();
w2.add(tisch);
w2.add(stuhl);
w2.add(schrank);
w2.add(tisch); // derselbe Artikel!!
System.out.println(w1);
Systemausgabe:
[Tisch(200), Tisch(200), Schrank(300), Stuhl(100)]
[Schrank(300), Tisch(200), Stuhl(100)]
wenn in „Artikel“ kein „equals()“ definiert ist
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Objektoiertierte Programmierung
K4 - 5
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Seite 1
Objektoiertierte Programmierung
K4 - 6
Ordnung auf Elementen: Interface „Comparable“
In „java.lang“:
public interface Comparable {
public int compareTo (Object o);
}
Definiert eine feste totale Ordnung auf der Klasse
In „java.util“:
public interface Comparator {
public int compare (Object o1, Object o2);
public boolean equals (Object obj);
}
Resultat kleiner/gleich/größer 0 wenn
"this" kleiner/gleich/größer als Objekt "o"
• Zu einer Klasse (Elemente einer Datenstruktur?) kann es
verschiedene Komparatoren geben, die über compare
Das Ergebnis des Objektvergleichs wird also als int angegeben!!
Standarddatentypen (z.B. String) implementieren
Comparable.
verschiedene Ordnungen definieren („<“, „>=“, ...)
• Die equals-Methode vergleicht Komparatoren.
„lexikographisch kleiner“
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Objektoiertierte Programmierung
K4 - 7
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Das Interface „Cloneable“
Objektoiertierte Programmierung
K4 - 8
Reflection: getClass(), forName(), ...
In „java.lang“:
public interface Cloneable {
// leeres Interface
}
In „Object“:
public Class getClass ();
In „Class“:
Public static Class forName(String name);
Die Klausel
• Die Klasse „Class“ bietet die „Reflection“-Möglichkeiten
von Java an:
class A implements Cloneable
sagt dem Java-Compiler, dass in der Klasse A die
Methode clone() aus Object verwendet werden darf
(also nicht selbstverständlich!).
– Auskunft über alle Bestandteile von Klassen: Methoden und
Exemplarvariablen, deren Typen und Zugiffsrechte ...
– über den „ClassLoader“ die Möglichkeit, zur Laufzeit Klassen
nachzuladen.
„flache Kopie“ => redefinieren!
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Ganz ähnlich: Das Interface „Comparator“
Objektoiertierte Programmierung
K4 - 9
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Erwartete Zusammenhänge
Objektoiertierte Programmierung
K4 - 10
Das Interface „java.io.Serializable“
public interface Comparable {
// leeres Interface
}
x.clone() != x
x.clone().getClass()
= = x.getClass()
x.clone().equals(x)
Die Klausel
class A implements Serializable
sagt dem Java-Compiler, dass in der Klasse A Serialisierung
verwendet werden darf.
Durch Serialisierung kann man ganze Objekt-Geflechte bequem
in einer Datei speichern und dadurch „persistent“ machen
aber alles NICHT
zwingend gefordert !!
d.h. über einen Programmlauf hinaus erhalten
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Objektoiertierte Programmierung
K4 - 11
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Seite 2
Objektoiertierte Programmierung
K4 - 12
Objekt-Serialisierung in Java
Objekt-Serialisierung: Abspeichern
import java.io.*;
• 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.
class XClass implements Serializable {
private int x;
public XClass (int x) {
this.x = x;
}
Datei mit Namen „Xfile.dat“
}
class ObjectOutputStream {
public ObjectOutputStream (OutputStream out)
throws IOException;
public void writeObject (Object obj)
throws IOException;
}
XClass xobj;
...
FileOutputStream fs =
new FileOutputStream("Xfile.dat");
ObjectOutputStream os =
new ObjectOutputStream(fs);
os.writeObject(xobj);
• Achtung: „statische“ und „transiente“ Attribute werden nicht
mitserialisiert!
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Objektoiertierte Programmierung
K4 - 13
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
class XClass implements Serializable {
private int x;
public XClass (int x) {
this.x = x;
}
}
Datei mit Namen „Xfile.dat“
Abstrakter Datentyp
(Schnittstelle)
Konkreter Datentyp
(Implementierung)
• Abstraktion:
• Konkretisierung:
– Operationen
– Verhalten der Operationen
• Theorie:
zum Lesen öffnen ...
FileInputStream fs = new
FileInputStream("Xfile.dat");
ObjectInputStream os =
new ObjectInputStream(fs);
xobj = (XClass) os.readObject();
– Datenstrukturen
– Effizienzfragen
• Praxis(Java):
– Abstrakte Klassen
– Interfaces
• Beispiel(Java):
– List
... deserialisieren und casten!
K4 - 15
Ada zum
Vergleich?
• Beispiel(Java):
– LinkedList
– ArrayList
Objektoiertierte Programmierung
K4 - 16
MyCollection.java (1)
• Eigene Implementierung einer Klasse des Collection-Frameworks:
class MyCollection
extends AbstractCollection implements Collection {
class MyCollection
extends AbstractCollection
implements Collection {
// „Minimalimplementierung“, s.u.
private class Elem { // eingebettete „innere“ Klasse
private Object elem;
private Elem next;
}
public Elem (Object elem, Elem next) {
this.elem = elem;
this.next = next;
}
// keine weiteren Operationen!
• Standard-Gerüste für Implementierung von Kollektionsklassen:
java.util.AbstractCollection,
java.util.AbstractList,...
}
• Eigene Kollektion muß mindestens definieren:
– add()
// falls sie erweiterbar sein soll
– size()
– iterator()
Objektoiertierte Programmierung
– Implementierungsalternativen
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Übungshalber: Selbstdefinierte Kollektion
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
• Theorie:
• Praxis(Java):
Objektoiertierte Programmierung
K4 - 14
– Instantiierbare Klassen
– Ausführbare Operationen
– Algebraische Spezifikationen
» Axiomensysteme
...
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Objektoiertierte Programmierung
4.2 Implementierung von Datenstrukturen
import java.io.*;
XClass xobj;
... und hier wird serialisiert!
...
Objekt-Serialisierung: Einlesen
...
zum Schreiben öffnen ...
...
private Elem start; // Exemplarvariablen ...
private Elem end;
// ... von MyCollection
private int size;
...
K4 - 17
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Seite 3
Objektoiertierte Programmierung
K4 - 18
MyCollection.java (3)
MyCollection.java (2)
...
private class MyCollectionIterator implements Iterator {
// Fortsetzung von MyCollection
public MyCollection() {
start = null; end = null; size = 0;
}
private Elem current;
public MyCollectionIterator() { current = start; }
public boolean hasNext() { return current != null; }
public boolean add (Object o) {
Elem e = new Elem(o,null);
if (start == null) start = e;
if (end != null) end.next = e;
end = e;
size++;
return true;
}
public Object next() {
Object o = current.elem;
current = current.next;
return o;
}
}
public Iterator iterator() {
return new MyCollectionIterator();
}
} // Ende von MyCollection
public int size() {
return size;
}
...
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Objektoiertierte Programmierung
K4 - 19
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Standard-Gerüst AbstractCollection(1)
// Fortsetzung von AbstractCollection (Ausschnitt)
...
public boolean add(Object o) {
throw new UnsupportedOperationException();
}
abgestützt auf nicht implementiertes „add()“ ...
• Minimal zu ergänzen:
public Iterator iterator();
public int size();
• Änderbare Kollektionen erfordern zusätzlich:
public boolean add(Object o);
public boolean addAll(Collection c) {
boolean modified = false;
Iterator e = c.iterator();
while (e.hasNext()) {
if(add(e.next()))modified = true;
}
return modified;
}
... und die abstrakte Methode iterator()
...
public abstract class AbstractCollection
implements Collection {
public abstract Iterator iterator();
public abstract int size();
public boolean isEmpty() {return size() == 0;}
...
abgestützt auf abstraktes „size()“
Objektoiertierte Programmierung
K4 - 21
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Standard-Gerüst AbstractCollection(3)
Objektoiertierte Programmierung
Objektoiertierte Programmierung
K4 - 22
Implementierungen im Collection-Framework
<<interface>>
// Fortsetzung von AbstractCollection (Ausschnitt)
...
public String toString() {
StringBuffer buf = new StringBuffer().append("[");
Iterator i = iterator();
boolean hasNext = i.hasNext();
while (hasNext) {
Object o = i.next();
buf.append(o = = this ? "(this Collection)" :
String.valueOf(o));
hasNext = i.hasNext();
if (hasNext) buf.append(", ");
warum nicht
}
toString()?
buf.append("]");
return buf.toString();
}
auch abgestützt auf iterator()
}
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
K4 - 20
Standard-Gerüst AbstractCollection(2)
• Zweck: Implementierung von Collections vereinfachen.
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Objektoiertierte Programmierung
Vererbung (extends)
Collection
<<interface>>
List
Implementierung (implements)
<<interface>>
Set
<<interface>>
SortedSet
ArrayList
HashSet
LinkedList
K4 - 23
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Seite 4
TreeSet
<<interface>>
Map
<<interface>>
SortedMap
HashMap
TreeMap
Objektoiertierte Programmierung
K4 - 24
Konkrete Datenstruktur: ArrayList
... tatsächlich noch etwas komplexer, z.B.:
public class ArrayList
extends AbstractList
implements List, Cloneable, Serializable {
<<interface>> Collection
<<interface>> List
private transient Object elementData[];
private int size;
AbstractCollection
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException
("Illegal Capacity: "+ initialCapacity);
„Herausfaktorisieren“
gemeinsamer
Funktionalität
AbstractList
AbstractSequentialList
this.elementData = new Object[initialCapacity];
}
ArrayList
....
LinkedList
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
}
Objektoiertierte Programmierung
K4 - 25
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Objektoiertierte Programmierung
Anfügen an ArrayList
Konkrete Datenstruktur: LinkedList
public boolean add(Object o) {
ensureCapacity(size + 1);
elementData[size++] = o;
return true;
public class LinkedList
extends AbstractSequentialList
implements List, Cloneable, Serializable {
private transient Entry header =
new Entry(null, null, null);
private transient int size = 0;
}
0
capacity
0
size capacity
public ListIterator listIterator(int index) {
return new ListItr(index);
size
}
implementiert als
doppelt verkettete Liste
....
}
o
o
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Objektoiertierte Programmierung
K4 - 27
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Vereinheitlicht
den Zugriff auf
verschiedene Listen
ListIterator
Objektoiertierte Programmierung
K4 - 28
ArrayList oder LinkedList?
• Gemessener relativer Aufwand für Operationen auf Listen:
(aus Eckel, Thinking in Java)
public interface ListIterator extends Iterator {
boolean hasNext();
Object next();
K4 - 26
// gibt es auch in Iterator
// gibt es auch in Iterator
boolean hasPrevious();
Object previous();
Typ
Lesen
ArrayList
LinkedList
110
1980
Iteration
490
220
Einfügen
Entfernen
3790
110
8730
110
int nextIndex();
int previousIndex();
• Stärken von ArrayList:
void remove();
// gibt es auch in Iterator
void set(Object o);
void add(Object o);
– wahlfreier Zugriff
– Iteration
• Stärken von LinkedList:
}
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
– Iteration
– Einfügen und Entfernen irgendwo in der Liste
Objektoiertierte Programmierung
K4 - 29
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Seite 5
Objektoiertierte Programmierung
K4 - 30
java.util.HashSet (Auszug)
Prinzip einer Hashfunktion
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Objektoiertierte Programmierung
0
Object
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();
}
hashCode(): int
o: Object
o.hashCode()
Direkte Ermittlung einer
Speicheradresse (z.B. Feldindex)
mit konstantem Zeitaufwand.
U.U. Kollisionen => auflösen!
capacity
K4 - 31
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
java.util.SortedSet (Auszug)
java.util.TreeSet
public interface SortedSet extends Set {
public
public
public
public
public
public
...
public
public
public
...
public
public
K4 - 32
Balancierter Rot-Schwarz-Baum,
vgl. Einführung i.d. Informatik II
• java.util.TreeSet:
public class TreeSet … implements SortedSet … {
…
boolean add (Object o);
boolean remove (Object o);
void clear();
boolean isEmpty();
boolean contains (Object o);
int size();
}
• Anwendungsbeispiel:
class Warengruppe {
private Set inhalt;
public Warengruppe (…) {
…
this.inhalt = new TreeSet();
} …
}
boolean equals (Object o);
int hashCode();
Iterator iterator();
Object first();
Object last(); ...
}
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Objektoiertierte Programmierung
Objektoiertierte Programmierung
K4 - 33
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Objektoiertierte Programmierung
K4 - 34
Anwendungsbeispiel mit TreeSet
HashSet oder TreeSet?
• Systemreaktion:
• Gemessener relativer Aufwand für Operationen auf Mengen:
(aus Eckel, Thinking in Java)
Exception in thread "main" java.lang.ClassCastException:
Artikel
at java.util.TreeMap.compare(TreeMap.java, Compiled Code)
Typ
• Modifikation der Klasse „Artikel“:
class Artikel implements Comparable { ...
public int compareTo (Object o) {
return name.compareTo(((Artikel)o).name);
}
}
Objektoiertierte Programmierung
Enthalten
7,4
6,6
Iteration
9,5
TreeSet
31,1
18,7
11,8
• Stärken von HashSet:
– unsortierte Mengen
– Verhalten von Iteration abhängig von reservierter Größe der Tabelle
• Stärken von TreeSet:
– sortierte Mengen
– Verhalten von Iteration abhängig von Anzahl der Elemente
hier ist ein Namensvergleich sinnvoll !
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Einfügen
HashSet
K4 - 35
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Seite 6
Objektoiertierte Programmierung
K4 - 36
4.3 Algorithmen auf Datenstrukturen
z.B. „Sortieren“ (aus Collections)
public class Collections {
eine sogenannte
„Utility-Klasse“
...
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)
}
public static void sort(List list) {
// zuerst in ein Array konvertieren:
Object a[] = list.toArray();
// dann Sortieralgorithmus aus „Arrays“:
Arrays.sort(a);
// zum Schluss per ListIterator zurück:
ListIterator i = list.listIterator();
for (int j=0; j<a.length; j++) {
i.next();
i.set(a[j]);
}
• 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(...)
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Sortieren in „Arrays“
Objektoiertierte Programmierung
}
K4 - 37
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
private static int iteratorBinarySearch
(List list, Object key) {
int low = 0; int high = list.size()-1;
ListIterator i = list.listIterator();
while (low <= high) {
int mid = (low + high) >> 1;
Object midVal = get(i, mid);
int cmp = ((Comparable)midVal).compareTo(key);
if (cmp < 0) low = mid + 1;
else if (cmp > 0) high = mid - 1;
else return mid; // key found
Verwendung von
„Comparable“
}
return -(low + 1); // key not found
}
private static void mergeSort
(Object src[], Object dest[],int low, int high) {
// Hier als Pseudocode:
// Insertion sort on smallest arrays
// Recursively sort halves of dest into src
// Optimization: If list is already sorted,
// just copy from src to dest.
// Merge sorted halves (now in src) into dest
}
„Arrays“ bietet auch Quicksort
Objektoiertierte Programmierung
K4 - 38
z.B. „Binärsuche“ (aus Collections)
auch eine
„Utility-Klasse“
public static void sort(Object[] a) {
Object aux[] = (Object[])a.clone();
mergeSort(aux, a, 0, a.length);
}
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Objektoiertierte Programmierung
K4 - 39
Lothar Schmitz UniBwM (teils nach Prof. Hußmann TUD)
Seite 7
Objektoiertierte Programmierung
K4 - 40
Herunterladen