21. Vorlesung (17.01.2013)

Werbung
Algorithmen und Datenstrukturen
Wintersemester 2012/13
21. Vorlesung
Interfaces und Generics
Jan-Henrik Haunert
Lehrstuhl für Informatik I
Übersicht
Liste und InsertionSort
• für Punkte
• für Objekte beliebiger Klassen
• für Objekte von Klassen, die ein(e) Nutzer(in) festlegen kann
Übersicht
Liste und InsertionSort
• für Punkte (Wiederholung vom 15.11.2012)
• für Objekte beliebiger Klassen
• für Objekte von Klassen, die ein(e) Nutzer(in) festlegen kann
InsertionSort für Punkte
Ein Punkt in der Ebene:
UML-Diagramm:
public class Punkt {
public double x;
public double y;
}
Punkt
+x:double
+y:double
Voraussetzung fürs Sortieren:
Definition einer Ordnung
y
p3
pi < pj genau dann, wenn
pi.x < pj.x oder
p1
( pi.x = pj.x und pi.y < pj.y)
p2
1
0
p4
= lexikographische Ordnung
0
1
x
InsertionSort für Punkte
Ein Punkt in der Ebene:
UML-Diagramm:
public class Punkt {
Punkt
public double x;
+x:double
public double y;
+y:double
public Punkt(double myX, double myY) {
+Punkt(double, double)
x = myX;
+compareTo(Punkt):int
y = myY;
}
/* gibt Wert < 0 fuer (this < p),
Wert > 0 fuer (this > p) und
0 fuer (this = p) zurueck */
public int compareTo(Punkt p) {
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
}
}
InsertionSort für Punkte
public class Sortierverfahren {
public static void insertionSort(int[] a) {
for (int j = 1; j < a.length; j++) {
int key = a[j];
int i = j - 1;
while (i >= 0 && a[i] > key) {
a[i + 1] = a[i];
i--;
}
a[i + 1] = key;
}
}
}
InsertionSort für Punkte
public class Sortierverfahren {
public static void insertionSort(Punkt[] a) {
for (int j = 1; j < a.length; j++) {
Punkt key = a[j];
int i = j - 1;
while (i >= 0 && a[i].compareTo(key) > 0) {
a[i + 1] = a[i];
i--;
}
a[i + 1] = key;
}
}
}
InsertionSort für Punkte
public class Sortierverfahren {
public static void main(String[] args) {
Punkt[] a = new Punkt[4];
a[0] = new Punkt(1, 2);
a[1] = new Punkt(1, 1);
a[2] = new Punkt(3, 1);
a[3] = new Punkt(4, 3);
insertionSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i].x + " " + a[i].y);
}
public static void insertionSort(Punkt[] a) {
//...
}
}
InsertionSort für Punkte
public class Sortierverfahren {
public static void main(String[] args) {
Punkt[] a = new Punkt[4];
a[0] = new Punkt(1, 2);
a[1] = new Punkt(1, 1);
a[2] = new Punkt(3, 1);
a[3] = new Punkt(4, 3);
insertionSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i].x + " " + a[i].y);
}
Ausgabe:
1.0 1.0
1.0 2.0
public static void insertionSort(Punkt[]
a) {
3.0
1.0
//...
}
4.0
3.0
}
InsertionSort für Punkte
Problem:
eigene Sortiermethode für jede Klasse notwendig
public static void insertionSort(Punkt[] a) {
//...
}
Liste für Punkte
x
head
nil
y
prev key next
nil
Liste für Punkte
x
head
nil
y
prev key next
nil
public class PunktListenElement {
public Punkt key;
public PunktListenElement prev;
public PunktListenElement next;
public PunktListenElement(Punkt k, PunktListenElement p) {
key = k;
next = p;
prev = null;
}
}
Liste für Punkte
public class PunktListe {
public PunktListenElement head;
public PunktListenElement insert(Punkt k) {
PunktListenElement x = new PunktListenElement(k, head);
if (head != null) {
head.prev = x;
}
head = x;
return x;
}
}
public class PunktListenElement {
public Punkt key;
public PunktListenElement prev;
public PunktListenElement next;
public PunktListenElement(Punkt k, PunktListenElement p) {
key = k;
next = p;
prev = null;
}
}
Liste für Punkte
public class PunktListenTest {
public static void main(String[] args) {
PunktListe l = new PunktListe();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
for (PunktListenElement p = l.head; p != null; p = p.next) {
System.out.println(p.key.x + " " + p.key.y);
}
}
}
Liste für Punkte
public class PunktListenTest {
public static void main(String[] args) {
PunktListe l = new PunktListe();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
for (PunktListenElement p = l.head; p != null; p = p.next) {
System.out.println(p.key.x + " " + p.key.y);
}
}
}
Ausgabe:
1.0 0.0
2.0 2.0
0.0 1.0
Liste für Punkte
public class PunktListenTest {
public static void main(String[] args) {
PunktListe l = new PunktListe();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
for (PunktListenElement p = l.head; p != null; p = p.next) {
System.out.println(p.key.x + " " + p.key.y);
}
}
}
Problem:
eigene Liste für jede Klasse notwendig
Liste für Punkte
public class PunktListenTest {
public static void main(String[] args) {
PunktListe l = new PunktListe();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
for (PunktListenElement p = l.head; p != null; p = p.next) {
System.out.println(p.key.x + " " + p.key.y);
}
}
}
Problem:
eigene Liste für jede Klasse notwendig
Lösung:
erstelle Liste für Objekte der Klasse java.lang.Object
Liste für Objekte
java.lang.Object
Punkt
• Jede Java-Klasse ist Unterklasse der Klasse java.lang.Object
• Eine Liste, die Objekte vom Typ java.lang.Object aufnehmen kann,
kann also jedes Objekt aufnehmen.
Liste für Objekte
public class PunktListe {
public PunktListenElement head;
public PunktListenElement insert(Punkt k) {
PunktListenElement x = new PunktListenElement(k, head);
if (head != null) {
head.prev = x;
}
head = x;
return x;
}
}
public class PunktListenElement {
public Punkt key;
public PunktListenElement prev;
public PunktListenElement next;
public PunktListenElement(Punkt k, PunktListenElement p) {
key = k;
next = p;
prev = null;
}
}
Liste für Objekte
public class Liste {
public ListenElement head;
public ListenElement insert(Object k) {
ListenElement x = new ListenElement(k, head);
if (head != null) {
head.prev = x;
}
head = x;
return x;
}
}
public class ListenElement {
public Object key;
public ListenElement prev;
public ListenElement next;
public ListenElement(Object k, ListenElement p) {
key = k;
next = p;
prev = null;
}
}
Liste für Objekte
public class PunktListenTest {
public static void main(String[] args) {
PunktListe l = new PunktListe();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
for (PunktListenElement p = l.head; p != null; p = p.next) {
System.out.println(p.key.x + " " + p.key.y);
}
}
}
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
for (ListenElement p = l.head; p != null; p = p.next) {
System.out.println(p.key.x + " " + p.key.y);
}
}
}
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
for (ListenElement p = l.head; p != null; p = p.next) {
System.out.println(p.key.x + " " + p.key.y);
}
}
Compiler: "p.key.x cannot be resolved or is not a field"
}
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
for (ListenElement p = l.head; p != null; p = p.next) {
Punkt myPunkt = (Punkt) p.key; //explizite Typkonvertierung
System.out.println(myPunkt.x + " " + myPunkt.y);
}
}
}
Ausgabe:
1.0 0.0
2.0 2.0
0.0 1.0
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(3.2));
l.insert(new Integer(4));
Wir können nun auch Objekte
anderer Klassen in die Liste einfügen
}
}
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(3.2));
l.insert(new Integer(4));
for (ListenElement p = l.head; p != null; p = p.next) {
Punkt myPunkt = (Punkt) p.key; //explizite Typkonvertierung
System.out.println(myPunkt.x + " " + myPunkt.y);
}
}
}
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(3.2));
l.insert(new Integer(4));
for (ListenElement p = l.head; p != null; p = p.next) {
Punkt myPunkt = (Punkt) p.key; //explizite Typkonvertierung
System.out.println(myPunkt.x + " " + myPunkt.y);
}
Ausgabe: Exception in thread "main"
}
}
java.lang.ClassCastException:
java.lang.Integer cannot be cast to Punkt
at ListenTest.main(ListenTest.java:12)
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(3.2));
l.insert(new Integer(4));
for (ListenElement p = l.head; p != null; p = p.next) {
if (p.key instanceof Punkt) {
Punkt myPunkt = (Punkt) p.key;
System.out.println(myPunkt.x + " " + myPunkt.y);
}
}
}
}
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(3.2));
l.insert(new Integer(4));
for (ListenElement p = l.head; p != null; p = p.next) {
if (p.key instanceof Punkt) {
Punkt myPunkt = (Punkt) p.key;
System.out.println(myPunkt.x + " " + myPunkt.y);
}
}
}
}
instanceof überprüft, ob Objekt zu
Klasse gehört
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(3.2));
l.insert(new Integer(4));
for (ListenElement p = l.head; p != null; p = p.next) {
if (p.key instanceof Punkt) {
Punkt myPunkt = (Punkt) p.key;
System.out.println(myPunkt.x + " " + myPunkt.y);
}
}
}
}
Ausgabe: 1.0 0.0
2.0 2.0
0.0 1.0
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(3.2));
l.insert(new Integer(4));
for (ListenElement p = l.head; p != null; p = p.next) {
if (p.key instanceof Punkt) {
Punkt myPunkt = (Punkt) p.key;
System.out.println(myPunkt.x + " " + myPunkt.y);
}
}
}
}
Ausgabe: 1.0 0.0
2.0 2.0 ...es werden nur die
0.0 1.0 Punkte ausgegeben
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(3.2));
l.insert(new Integer(4));
for (ListenElement p = l.head; p != null; p = p.next) {
//gib Ergebnis von p.key.toString() aus:
System.out.println(p.key);
}
}
}
Ausgabe:
4
3.2
Punkt@c3c749
Punkt@150bd4d
Punkt@1bc4459
Liste für Objekte
java.lang.Object
+toString():String
java.lang.Double
java.lang.Integer
+toString():String
+toString():String
Punkt
for (ListenElement p = l.head; p != null; p = p.next) {
//gib Ergebnis von p.key.toString() aus:
System.out.println(p.key);
}
Ausgabe:
4
3.2
Punkt@c3c749
Punkt@150bd4d
Punkt@1bc4459
toString (Klasse Integer)
toString (Klasse Double)
toString (Klasse Object)
Liste für Objekte
java.lang.Object
+toString():String
java.lang.Double
java.lang.Integer
Punkt
+toString():String
+toString():String
+toString():String
public class Punkt {
public double x;
public double y;
public String toString() {
return "(" + x + ", " + y + ")";
}
//...
}
Liste für Objekte
java.lang.Object
+toString():String
java.lang.Double
java.lang.Integer
Punkt
+toString():String
+toString():String
+toString():String
public class Punkt {
public double x;
public double y;
public String toString() {
return "(" + x + ", " + y + ")";
}
//...
}
Methode toString
der Klasse Object
wird überschrieben
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(3.2));
l.insert(new Integer(4));
for (ListenElement p = l.head; p != null; p = p.next) {
//gib Ergebnis von p.key.toString() aus:
System.out.println(p.key);
}
java.lang.Object
}
}
Ausgabe:
4
3.2
Punkt@c3c749
Punkt@150bd4d
Punkt@1bc4459
+toString():String
Punkt
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(3.2));
l.insert(new Integer(4));
for (ListenElement p = l.head; p != null; p = p.next) {
//gib Ergebnis von p.key.toString() aus:
System.out.println(p.key);
}
java.lang.Object
}
}
Ausgabe:
4
3.2
(1.0, 0.0)
(2.0, 2.0)
(0.0, 1.0)
+toString():String
Punkt
+toString():String
InsertionSort für Punkte
Problem:
eigene Sortiermethode für jede Klasse notwendig
public static void insertionSort(Punkt[] a) {
//...
}
InsertionSort für Objekte
public class Sortierverfahren {
public static void insertionSort(Punkt[] a) {
for (int j = 1; j < a.length; j++) {
Punkt key = a[j];
int i = j - 1;
while (i >= 0 && a[i].compareTo(key) > 0) {
a[i + 1] = a[i];
i--;
}
a[i + 1] = key;
}
}
}
InsertionSort für Objekte
public class Sortierverfahren {
public static void insertionSort(Object[] a) {
for (int j = 1; j < a.length; j++) {
Object key = a[j];
int i = j - 1;
while (i >= 0 && a[i].compareTo(key) > 0) {
a[i + 1] = a[i];
i--;
}
a[i + 1] = key;
}
}
}
InsertionSort für Objekte
public class Sortierverfahren {
public static void insertionSort(Object[] a) {
for (int j = 1; j < a.length; j++) {
Object key = a[j];
int i = j - 1;
while (i >= 0 && a[i].compareTo(key) > 0) {
a[i + 1] = a[i];
i--;
Compiler: "The method compareTo(Object)
}
a[i + 1] = key;
is undefined for the type Object"
}
}
}
InsertionSort für Objekte
public class Sortierverfahren {
public static void insertionSort(Comparable[] a) {
for (int j = 1; j < a.length; j++) {
Comparable key = a[j];
int i = j - 1;
while (i >= 0 && a[i].compareTo(key) > 0) {
a[i + 1] = a[i];
i--;
}
a[i + 1] = key;
}
}
}
InsertionSort für Objekte
public class Sortierverfahren {
public static void insertionSort(Comparable[] a) {
for (int j = 1; j < a.length; j++) {
Comparable key = a[j];
int i = j - 1;
while (i >= 0 && a[i].compareTo(key) > 0) {
a[i + 1] = a[i];
i--;
}
a[i + 1] = key; To Do:
}
Definiere Klasse Comparable,
}
so dass sichergestellt ist,
}
dass Objekte von Unterklassen
vergleichbar sind
InsertionSort für Objekte
public class Comparable {
public int compareTo(Object o) {
//?
}
}
To Do:
Definiere Klasse Comparable,
so dass sichergestellt ist,
dass Objekte von Unterklassen
vergleichbar sind
InsertionSort für Objekte
public class Comparable {
public int compareTo(Object o) {
//?
}
}
Es fällt uns schwer, eine
Definition zu finden.
allgemeine
InsertionSort für Objekte
public class Comparable {
public int compareTo(Object o) {
//?
}
}
Es fällt uns schwer, eine
allgemeine
Definition zu finden.
Wir sollten daher verbieten, Instanzen
unserer Klasse Comparable zu erzeugen.
InsertionSort für Objekte
public abstract class Comparable {
public abstract int compareTo(Object o);
}
Es fällt uns schwer, eine allgemeine
Definition zu finden.
Wir sollten daher verbieten, Instanzen
unserer Klasse Comparable zu erzeugen.
Deshalb:
abstract
InsertionSort für Objekte
public abstract class Comparable {
public abstract int compareTo(Object o);
}
Die Klasse unserer Vergleichsobjekte
hat evtl. bereits eine Oberklasse.
Tier
Elefant
InsertionSort für Objekte
public abstract class Comparable {
public abstract int compareTo(Object o);
}
Die Klasse unserer Vergleichsobjekte
hat evtl. bereits eine Oberklasse.
Tier
Comparable
Elefant
Mehrfachvererbung ist
verboten!
InsertionSort für Objekte
public interface Comparable {
public int compareTo(Object o);
}
Die Klasse unserer Vergleichsobjekte
hat evtl. bereits eine Oberklasse.
Deshalb:
interface
<<Interface>>
Comparable
Tier
Elefant
InsertionSort für Objekte
Interfaces ähneln abstrakten Klassen, die ausschließlich
abstrakte Methoden besitzen
(keine Attribute und keine implementierten Methoden).
Unterschied:
Eine Klasse kann mehrere Interfaces implementieren,
aber nur eine Klasse (direkt) erweitern.
<<Interface>>
Comparable
Tier
Elefant
InsertionSort für Objekte
public interface Comparable {
public int compareTo(Object o);
}
Interface Comparable
war bis Java-Version 1.4
so im Paket java.lang definiert.
InsertionSort für Objekte
public class Punkt {
public double x;
public double y;
public Punkt(double myX, double myY) {
x = myX;
y = myY;
}
/* gibt Wert < 0 fuer (this < p),
Wert > 0 fuer (this > p) und
0 fuer (this = p) zurueck */
public int compareTo(Punkt p) {
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
}
}
InsertionSort für Objekte
public class Punkt implements Comparable {
public double x;
public double y;
Compiler: "The type Punkt must
public Punkt(double myX, double myY) {
implement the inherited abstract
x = myX;
method Comparable.compareTo(Object)"
y = myY;
}
/* gibt Wert < 0 fuer (this < p),
Wert > 0 fuer (this > p) und
0 fuer (this = p) zurueck */
public int compareTo(Punkt p) {
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
}
}
InsertionSort für Objekte
public class Punkt implements Comparable {
public double x;
public double y;
public Punkt(double myX, double myY) {
x = myX;
y = myY;
}
/* gibt Wert < 0 fuer (this < p),
Wert > 0 fuer (this > p) und
0 fuer (this = p) zurueck */
public int compareTo(Object o) {
Punkt p = (Punkt) o;
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
}
}
InsertionSort für Objekte
public class Sortierverfahren {
public static void main(String[] args) {
Punkt[] a = new Punkt[4];
a[0] = new Punkt(1, 2);
a[1] = new Punkt(1, 1);
a[2] = new Punkt(3, 1);
a[3] = new Punkt(4, 3);
insertionSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i].x + " " + a[i].y);
}
public static void insertionSort(Comparable[] a) {
//...
}
}
InsertionSort für Objekte
public class Sortierverfahren {
public static void main(String[] args) {
Punkt[] a = new Punkt[4]; Hier wird Feld mit
a[0] = new Punkt(1, 2);
Punkt-Objekten übergeben
a[1] = new Punkt(1, 1);
a[2] = new Punkt(3, 1);
Hier wird Feld mit
a[3] = new Punkt(4, 3);
Comparable-Objekten
insertionSort(a);
entgegengenommen
for (int i = 0; i < a.length; i++)
System.out.println(a[i].x + " " + a[i].y);
}
public static void insertionSort(Comparable[] a) {
//...
}
}
InsertionSort für Objekte
public class Sortierverfahren {
public static void main(String[] args) {
Punkt[] a = new Punkt[4];
a[0] = new Punkt(1, 2);
a[1] = new Punkt(1, 1);
a[2] = new Punkt(3, 1);
a[3] = new Punkt(4, 3);
insertionSort(a);
Ausgabe:
1.0 1.0
for (int i = 0; i < a.length; i++)
2.0
System.out.println(a[i].x + 1.0
" " + a[i].y);
}
3.0
1.0
public static void insertionSort(Comparable[] a) {
//...
4.0 3.0
}
}
InsertionSort für Objekte
GeoFigur
+m:Punkt
+GeoFigur(Punkt)
+getFlaeche():double
+compareTo(GeoFigur):int
Quadrat
Kreis
-a:double
-r:double
+Quadrat(Punkt, double)
+getFlaeche():double
+setA(double)
+getA():double
+Kreis(Punkt, double)
+getFlaeche():double
+setR(double)
+getR():double
InsertionSort für Objekte
<<Interface>>
Comparable
+compareTo(Object):int
GeoFigur
+m:Punkt
+GeoFigur(Punkt)
+getFlaeche():double
+compareTo(Object):int
Quadrat
Kreis
-a:double
-r:double
+Quadrat(Punkt, double)
+getFlaeche():double
+setA(double)
+getA():double
+Kreis(Punkt, double)
+getFlaeche():double
+setR(double)
+getR():double
InsertionSort für Objekte
Klasse GeoFigur in Java:
public class GeoFigur {
public Punkt m;
public GeoFigur(Punkt myM) {
m = myM;
}
public double getFlaeche() {
return 0.0;
}
public int compareTo(GeoFigur key) {
if (this.getFlaeche() > key.getFlaeche())
return 1;
if (this.getFlaeche() < key.getFlaeche())
return -1;
return 0;
}
}
InsertionSort für Objekte
Klasse GeoFigur in Java:
public class GeoFigur implements Comparable {
public Punkt m;
public GeoFigur(Punkt myM) {
m = myM;
}
public double getFlaeche() {
return 0.0;
}
public int compareTo(Object o) {
GeoFigur key = (GeoFigur) o;
if (this.getFlaeche() > key.getFlaeche())
return 1;
if (this.getFlaeche() < key.getFlaeche())
return -1;
return 0;
}
}
InsertionSort für Objekte
Sortieren:
public class Sortierverfahren {
public static void main(String[] args) {
GeoFigur[] a = new GeoFigur[4];
a[0] = new Quadrat(new Punkt(0.0, 0.0), 2.0);
a[1] = new Quadrat(new Punkt(1.0, 2.0), 4.0);
a[2] = new Kreis(new Punkt(2.0, 0.0), 2.0);
a[3] = new Kreis(new Punkt(0.0, 1.0), 4.0);
insertionSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i].getClass().toString()
+ " " + a[i].getFlaeche());
}
public static void insertionSort(GeoFigur[] a) {
//...
}
}
InsertionSort für Objekte
Sortieren:
public class Sortierverfahren {
public static void main(String[] args) {
GeoFigur[] a = new GeoFigur[4];
a[0] = new Quadrat(new Punkt(0.0, 0.0), 2.0);
a[1] = new Quadrat(new Punkt(1.0, 2.0), 4.0);
a[2] = new Kreis(new Punkt(2.0, 0.0), 2.0);
a[3] = new Kreis(new Punkt(0.0, 1.0), 4.0);
insertionSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i].getClass().toString()
+ " " + a[i].getFlaeche());
}
public static void insertionSort(Comparable[] a) {
//...
}
}
InsertionSort für Objekte
Sortieren:
public class Sortierverfahren {
public static void main(String[] args) {
GeoFigur[] a = new GeoFigur[4];
a[0] = new Quadrat(new Punkt(0.0, 0.0), 2.0);
a[1] = new Quadrat(new Punkt(1.0, 2.0), 4.0);
a[2] = new Kreis(new Punkt(2.0, 0.0), 2.0);
a[3] = new Kreis(new Punkt(0.0, 1.0), 4.0);
insertionSort(a);
Ausgabe:
class Quadrat 4.0
class
Kreis 12.566370614359172
}
public static void insertionSort(Comparable[] a) {
class
//... Quadrat 16.0
}
class
Kreis 50.26548245743669
}
for (int i = 0; i < a.length; i++)
System.out.println(a[i].getClass().toString()
+ " " + a[i].getFlaeche());
InsertionSort für Objekte
Sortieren:
public class Sortierverfahren {
public static void main(String[] args) {
GeoFigur[] a = new GeoFigur[4];
a[0] = new Punkt(0.0, 0.0);
a[1] = new Quadrat(new Punkt(1.0, 2.0), 4.0);
a[2] = new Kreis(new Punkt(2.0, 0.0), 2.0);
a[3] = new Kreis(new Punkt(0.0, 1.0), 4.0);
insertionSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i].getClass().toString()
+ " " + a[i].getFlaeche());
}
public static void insertionSort(Comparable[] a) {
//...
}
}
InsertionSort für Objekte
Sortieren:
public class Sortierverfahren {
public static void main(String[] args) {
Compiler:
Type mismatch:
cannot convert
from Punkt to
GeoFigur
GeoFigur[] a = new GeoFigur[4];
a[0] = new Punkt(0.0, 0.0);
a[1] = new Quadrat(new Punkt(1.0, 2.0), 4.0);
a[2] = new Kreis(new Punkt(2.0, 0.0), 2.0);
a[3] = new Kreis(new Punkt(0.0, 1.0), 4.0);
insertionSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i].getClass().toString()
+ " " + a[i].getFlaeche());
}
public static void insertionSort(Comparable[] a) {
//...
}
}
InsertionSort für Objekte
Sortieren:
public class Sortierverfahren {
public static void main(String[] args) {
Comparable[] a = new Comparable[4];
a[0] = new Punkt(0.0, 0.0);
a[1] = new Quadrat(new Punkt(1.0, 2.0), 4.0);
a[2] = new Kreis(new Punkt(2.0, 0.0), 2.0);
a[3] = new Kreis(new Punkt(0.0, 1.0), 4.0);
insertionSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i]);
}
public static void insertionSort(Comparable[] a) {
//...
}
}
InsertionSort für Objekte
Sortieren:
public class Sortierverfahren {
public static void main(String[] args) {
Comparable[] a = new Comparable[4];
a[0] = new Punkt(0.0, 0.0);
a[1] = new Quadrat(new Punkt(1.0, 2.0), 4.0);
a[2] = new Kreis(new Punkt(2.0, 0.0), 2.0);
a[3] = new Kreis(new Punkt(0.0, 1.0), 4.0);
insertionSort(a);
Ausgabe: for (int i = 0; i < a.length; i++)
System.out.println(a[i]);
Exception in thread "main" java.lang.ClassCastException:
}
Quadrat cannot be cast to Punkt
public static void insertionSort(Comparable[] a) {
at Punkt.compareTo(Punkt.java:12)
//...
at Sortierverfahren.insertionSort(Sortierverfahren.java:21)
}
at
} Sortierverfahren.main(Sortierverfahren.java:9)
InsertionSort für Objekte
public class Punkt implements Comparable {
public double x;
public double y;
public Punkt(double myX, double myY) {
x = myX;
y = myY;
}
/* gibt Wert < 0 fuer (this < p),
Wert > 0 fuer (this > p) und
0 fuer (this = p) zurueck */
public int compareTo(Object o) {
Punkt p = (Punkt) o;
if (this.x < p.x) return -1;
Ausgabe:
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y
== p.y)
return
0;
Exception
in thread
"main"
java.lang.ClassCastException:
}
Quadrat
cannot be cast to Punkt
return 1;
at Punkt.compareTo(Punkt.java:12)
at} Sortierverfahren.insertionSort(Sortierverfahren.java:21)
}at Sortierverfahren.main(Sortierverfahren.java:9)
InsertionSort für Objekte
public class Punkt implements Comparable {
public double x;
public double y;
public Punkt(double myX, double myY) {
x = myX;
y = myY;
}
/* gibt Wert < 0 fuer (this < p),
Wert > 0 fuer (this > p) und
0 fuer (this = p) zurueck */
public int compareTo(Object o) {
Punkt p = (Punkt) o;
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
}
}
InsertionSort für Objekte
public class Punkt implements Comparable {
public double x;
public double y;
public Punkt(double myX, double myY) {
x = myX;
y = myY;
}
public int compareTo(Object o) {
if (o instanceof Punkt) {
Punkt p = (Punkt) o;
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
} else {
//?
}
}
}
InsertionSort für Objekte
public class Punkt implements Comparable {
public double x;
public double y;
public Punkt(double myX, double myY) {
x = myX;
y = myY;
}
public int compareTo(Object o) {
if (o instanceof Punkt) {
Punkt p = (Punkt) o;
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
} else {
Es wäre gut, wenn wir wüssten,
//?
mit was für Objekten
}
}
wir zu rechnen haben.
}
InsertionSort für Objekte
public interface Comparable {
public int compareTo(Object o);
}
InsertionSort für Objekte
public interface Comparable<T> {
public int compareTo(T o);
}
Seit Java Version 5 können
generische Datentypen
definiert werden.
InsertionSort für Objekte
public interface Comparable<T> {
public int compareTo(T o);
}
Seit Java Version 5 können
generische Datentypen
definiert werden.
Typparameter
(Platzhalter für den
Namen einer Klasse)
InsertionSort für Objekte
public interface Comparable<T> {
public int compareTo(T o);
}
public class Punkt implements Comparable {
//...
public int compareTo(Object o) {
Punkt p = (Punkt) o;
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
}
}
InsertionSort für Objekte
public interface Comparable<T> {
public int compareTo(T o);
}
public class Punkt implements Comparable<Punkt> {
//...
public int compareTo(Punkt p) {
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
}
}
InsertionSort für Objekte
public interface Comparable<T> {
public int compareTo(T o);
}
Für Typparameter wird Typargument (Punkt) eingesetzt.
public class Punkt implements Comparable<Punkt> {
//...
public int compareTo(Punkt p) {
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
}
}
InsertionSort für Objekte
public interface Comparable<T> {
public int compareTo(T o);
}
Für Typparameter wird Typargument (Punkt) eingesetzt.
public class Punkt implements Comparable<Punkt> {
//...
public int compareTo(Punkt p) {
if (this.x < p.x) return -1;
if (this.x == p.x) {
if (this.y < p.y) return -1;
if (this.y == p.y) return 0;
}
return 1;
}
}
Punkte können nur mit Punkten
verglichen werden!
InsertionSort für Objekte
public class Sortierverfahren {
public static void main(String[] args) {
Punkt[] a = new Punkt[4];
a[0] = new Punkt(1, 2);
a[1] = new Punkt(1, 1);
a[2] = new Punkt(3, 1);
a[3] = new Punkt(4, 3);
insertionSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i].x + " " + a[i].y);
}
public static void insertionSort(Comparable[] a) {
//...
}
}
InsertionSort für Objekte
public class Sortierverfahren {
public static void main(String[] args) {
Punkt[] a = new Punkt[4];
a[0] = new Punkt(1, 2);
a[1] = new Punkt(1, 1);
a[2] = new Punkt(3, 1);
a[3] = new Punkt(4, 3);
insertionSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i].x + " " + a[i].y);
}
public static <T extends Comparable<T>> void
insertionSort (T[] a) {
//...
}
}
InsertionSort für Objekte
generische Methode:
public static <T extends Comparable<T>> void
insertionSort (T[] a) {
//...
}
}
InsertionSort für Objekte
generische Methode:
Nimmt Feld mit Objekten einer Klasse T entgegen
public static <T extends Comparable<T>> void
insertionSort (T[] a) {
//...
}
}
InsertionSort für Objekte
generische Methode:
Nimmt Feld mit Objekten einer Klasse T entgegen
wobei T für beliebige Klasse steht, die diese Bedingung erfüllt
public static <T extends Comparable<T>> void
insertionSort (T[] a) {
//...
}
}
InsertionSort für Objekte
public class Sortierverfahren {
public static <T extends Comparable<T>> void
insertionSort(T[] a) {
for (int j = 1; j < a.length; j++) {
T key = a[j];
int i = j - 1;
while (i >= 0 && a[i].compareTo(key) > 0) {
a[i + 1] = a[i];
i--;
}
a[i + 1] = key;
}
}
}
Liste für Objekte
public class Liste {
public ListenElement head;
public ListenElement insert(Object k) {
ListenElement x = new ListenElement(k, head);
if (head != null) {
head.prev = x;
}
head = x;
return x;
}
}
public class ListenElement {
public Object key;
public ListenElement prev;
public ListenElement next;
public ListenElement(Object k, ListenElement p) {
key = k;
next = p;
prev = null;
}
}
Liste für Objekte
public class List<T> {
public ListItem<T> head;
public ListItem<T> insert(T k) {
ListItem<T> x = new ListItem<T>(k, head);
if (head != null) {
head.prev = x;
}
head = x;
return x;
}
}
public class ListItem<T> {
public T key;
public ListItem<T> prev;
public ListItem<T> next;
public ListItem (T k, ListItem<T> p) {
key = k;
next = p;
prev = null;
}
}
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
Liste l = new Liste();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
for (ListenElement p = l.head; p != null; p = p.next) {
if (p.key instanceof Punkt) {
Punkt myPunkt = (Punkt) p.key;
System.out.println(myPunkt.x + " " + myPunkt.y);
}
}
}
}
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
List<Punkt> l = new List<Punkt>();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
for (ListItem<Punkt> p = l.head; p != null; p = p.next) {
System.out.println(p.key.x + " " + p.key.y);
}
}
}
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
List<Punkt> l = new List<Punkt>();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
for (ListItem<Punkt> p = l.head; p != null; p = p.next) {
System.out.println(p.key.x + " " + p.key.y);
}
}
}
Ausgabe: 1.0 0.0
2.0 2.0
0.0 1.0
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
List<Punkt> l = new List<Punkt>();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(2.0));
for (ListItem<Punkt> p = l.head; p != null; p = p.next) {
System.out.println(p.key.x + " " + p.key.y);
}
}
}
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
List<Punkt> l = new List<Punkt>();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(2.0));
for (ListItem<Punkt> p = l.head; p != null; p = p.next) {
System.out.println(p.key.x + " " + p.key.y);
}
}
}
Compiler:
"The method insert(Punkt) in
the type List<Punkt> is not applicable
for the arguments (Double)"
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
List<Object> l = new List<Object>();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(2.0));
for (ListItem<Object> p = l.head; p != null; p = p.next) {
System.out.println(p.key);
}
}
}
Liste für Objekte
public class ListenTest {
public static void main(String[] args) {
List<Object> l = new List<Object>();
l.insert(new Punkt(0.0, 1.0));
l.insert(new Punkt(2.0, 2.0));
l.insert(new Punkt(1.0, 0.0));
l.insert(new Double(2.0));
for (ListItem<Object> p = l.head; p != null; p = p.next) {
System.out.println(p.key);
}
}
}
Ausgabe:
2.0
(1.0, 0.0)
(2.0, 2.0)
(0.0, 1.0)
Schluss
Generische Datentypen/Methoden
erlauben es,
Datenstrukturen/Algorithmen
so zu implementieren,
dass sie für verschiedene Datentypen angewandt
werden können.
Herunterladen