Algorithmen und Datenstrukturen Übersicht Liste und InsertionSort • für Punkte • für Objekte beliebiger Klassen • für Objekte von Klassen, die ein(e) Nutzer(in) festlegen kann Wintersemester 2012/13 21. Vorlesung Interfaces und Generics Jan-Henrik Haunert Lehrstuhl für Informatik I InsertionSort für Punkte Ein Punkt in der Ebene: InsertionSort für Punkte UML-Diagramm: public class Punkt { public double x; public double y; } Punkt +x:double +y:double Voraussetzung fürs Sortieren: Definition einer Ordnung y pi < pj genau dann, wenn p3 pi.x < pj.x oder p1 p2 1 0 ( pi.x = pj.x und pi.y < pj.y) p4 = lexikographische Ordnung 0 1 x Ein Punkt in der Ebene: 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; } } } 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 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; ngt t i++) System.out.println(a[i].x .x x + " " + a[i].y); } Ausgabe: 1.0 1.0 1.0 2.0 public static void insertionSort(Punkt[] onS S 3.0 1.0 a) { //... } 4.0 3.0 } 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; } } InsertionSort für Punkte Problem: eigene Sortiermethode für jede Klasse notwendig public static void insertionSort(Punkt[] a) { //... } 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 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); } } } 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 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 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 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 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 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) { 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 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)); 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)); 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); } 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: Exception in thread "main" } } java.lang.ClassCastException: java.lang.Integer cannot be cast to Punkt at ListenTest.main(ListenTest.java:12) instanceof überprüft, ob Objekt zu Klasse gehört } } Liste für Objekte 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)); } } 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)); 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); } } for (ListenElement p = l.head; p != null; p = p.next) { //gib Ergebnis von p.key.toString() aus: System.out.println(p.key); } Ausgabe: 1.0 0.0 2.0 2.0 ...es werden nur die 0.0 1.0 Punkte ausgegeben Liste für Objekte Ausgabe: 4 3.2 Punkt@c3c749 Punkt@150bd4d Punkt@1bc4459 Liste für Objekte java.lang.Object java.lang.Object +toString():String +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) 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 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)); } 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)); 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 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 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(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 Ausgabe: 4 3.2 (1.0, 0.0) (2.0, 2.0) (0.0, 1.0) +toString():String Punkt +toString():String 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 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 abstract class Comparable { public abstract int compareTo(Object o); } InsertionSort für Objekte public abstract class Comparable { public abstract int compareTo(Object o); } Es fällt uns schwer, eine allgemeine Definition zu finden. Die Klasse unserer Vergleichsobjekte hat evtl. bereits eine Oberklasse. Wir sollten daher verbieten, Instanzen unserer Klasse Comparable zu erzeugen. Tier Deshalb: Comparable abstract Elefant InsertionSort für Objekte InsertionSort für Objekte public interface Comparable { public int compareTo(Object o); } Interfaces ähneln abstrakten Klassen, die ausschließlich abstrakte Methoden besitzen (keine Attribute und keine implementierten Methoden). Die Klasse unserer Vergleichsobjekte hat evtl. bereits eine Oberklasse. Deshalb: Unterschied: Eine Klasse kann mehrere Interfaces implementieren, aber nur eine Klasse (direkt) erweitern. interface <<Interface>> Comparable Tier Elefant InsertionSort für Objekte Interface Comparable war bis Java-Version 1.4 so im Paket java.lang definiert. <<Interface>> Comparable Tier Elefant public interface Comparable { public int compareTo(Object o); } Mehrfachvererbung ist verboten! InsertionSort für Objekte public class Punkt implements Comparable { public double x; public double y; Compiler: "The type Punkt must public Punkt(double myX, X, 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]; 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 InsertionSort für Objekte <<Interface>> Comparable 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); +compareTo(Object):int GeoFigur +m:Punkt Ausgabe: 1.0 1.0 for (int i = 0; i < a.length; h; i++) 2.0 System.out.println(a[i].x + 1.0 " " + a[i].y); } 3.0 1.0a) { public static void insertionSort(Comparable[] or r //... 4.0 3.0 } +GeoFigur(Punkt) +getFlaeche():double +compareTo(Object):int Quadrat } 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; } } 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 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: InsertionSort für Objekte Sortieren: public class Sortierverfahren { public static void main(String[] args) { 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); 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); Ausgabe: for (int i = 0; i < a.length; i++) class Quadrat 4.0 System.out.println(a[i].getClass().toString() + " " + a[i].getFlaeche()); 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()); } public static void insertionSort(Comparable[] a) { //... } } InsertionSort für Objekte Sortieren: Compiler: Type mismatch: cannot convert from Punkt to GeoFigur 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 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 if (this.x (this (this.x < p.x) p.x) x) return return -1; 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) 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; 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 { 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. 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); } 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); } 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) { //... } } public static <T extends Comparable<T>> void insertionSort (T[] a) { //... } } InsertionSort für Objekte 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; } } 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 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)); 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) { 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<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)); for (ListItem<Object> p = l.head; p != null; p = p.next) { } } } } } } Compiler: "The method insert(Punkt) in the type List<Punkt> is not applicable for the arguments (Double)" Schluss Generische Datentypen/Methoden erlauben es, Datenstrukturen/Algorithmen l.insert(new Double(2.0)); System.out.println(p.key); System.out.println(p.key.x + " " + p.key.y); Ausgabe: 2.0 (1.0, 0.0) (2.0, 2.0) (0.0, 1.0) so zu implementieren, dass sie für verschiedene Datentypen angewandt werden können.