Foliensatz 16

Werbung
CS1005
Objektorientierte Programmierung
Bachelor of Science (Informatik)
Th Letschert
Klassenbibliothek
Kollektionen
Anforderungen der Kollektionen an ihre Elemente
Iteratoren
Seite 1
© Th Letschert
Klassenbibliothek
Seite 2
Th Letschert
Java = Sprache + Bibliothek
Java = Sprachkern + Klassenbibliothek
Klassenbibliothek
Sammlung von vordefinierten Klassen
für allgemeine wiederkehrende Aufgaben
Java Klassenbibliothek
definiert als
<Java Versionsbezeichnung> API Specification
z.B.
Java Platform Standard Edition 6.0 API Specification
siehe java.sun.com/docs , http://java.sun.com/javase/6/docs/
realisiert in den Java-Distributionen z.B.
JDK-1.6.0 (Java Development Kit 1.6.0)
organisiert in Pakete
java.applet
... viele viele weitere Pakete mit vielen Klassen ...
org.xml.sax.helpers
Seite 3
Th Letschert
Klassenbibliothek
Klassenbibliothek
Organisiert in Pakete
Beispiel-Pakete jeweils mit einer Beispiel-Klasse und einer Beispiel-Methode
• javax.swing
• JOptionsPane
• JOptionsPane.showMessageDialog
• java.lang
• Integer
• Integer. parseInt
• java.util
• Arrays
• Arrays .sort
Seite 4
Th Letschert
Klassenbibliothek
wichtige Pakete der Klassenbibliothek
●
java.lang
enthält Dinge von fundamentaler Bedeutung, z.B.:
●
●
●
●
●
Integer
Math
Object
...
java.util
allgemein verwendbare Hilfsklassen (Utilities)
speziell für die Arbeit mit Feldern und anderen Kollektionen, z.B.:
●
●
●
●
●
●
Arrays
Collections
ArrayList
HashSet
....
java.awt, javax.swing
enthält Nützliches zur Konstruktion graphischer Oberflächen
Seite 5
Th Letschert
Klassenbibliothek: API Doku immer bereit halten !
Seite 6
Th Letschert
Kollektionen
Seite 7
Th Letschert
Kollektionen
Kollektionen (Collection):
Abstrakte Datentypen zur Verwaltung von Elementen
in Java nicht als vordefinierte Sprachelemente verfügbar,
sondern als Bestandteil der Standard-Bibliothek
Beispiele: Mengen, Listen, Abbildungen
Java-Klassenbibliothek
Paket java.util enthält Schnittstellen und Klassen zum Umgang mit
Kollektionen
Collection Framework:
Zusammenhängendes System aus Klassen- und
Schnittstellendefinitionen in der Klassenbibliothek
Kollektionstypen
der Java-Klassenbibliothek gibt es in drei Grund-Varianten
List
Set
Map
Listen
Mengen
Abbildungen
Seite 8
Th Letschert
Kollektionen: Liste
ArrayList (java.util.ArrayList)
Als Typ einer Variablen oder eines
Parameters möglichst ein Interface
verwenden!
Eine Klasse die
den ADT Liste
auf Basis von Arrays implementiert
import java.util.ArrayList;
import java.util.List;
jede Art Integer-Liste ist
willkommen
public final class Test {
public static void lister(List<Integer> l){
for (Integer i : l)
System.out.println(i);
}
jede Art Integer-Liste ist
als Wert erlaubt
public static void main(String[] args) {
List<Integer> l = new ArrayList<Integer>();
l.add(5);
lister(l);
eine Array-basierte
Implementierung von
}
}
ArrayList als List-Implementierung
Seite 9
Liste erzeugen
Th Letschert
Kollektionen: Liste
import
import
import
import
import
java.io.File;
java.util.ArrayList;
java.util.Collections;
java.util.List;
javax.swing.JFileChooser;
Beispiel: MP3-Dateien in einem
Verzeichnis sortiert auflisten
public final class MusicCollection {
private MusicCollection() { }
private static File chooseFile(String msg) {
JFileChooser fc = new JFileChooser();
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int returnVal = fc.showDialog(n ull, msg);
if (returnVal == JFileChooser.APPROVE_OPTION) {
ret urn fc.getSelectedFile();
} else { retur n n ull; }
}
public static void main(String[] args) {
File directory = chooseFile("Verzeichnis mit Musik");
Liste erzeugen: Größe nach
Bedarf !
Element zu Liste hinzu fügen
List<String> songs = new ArrayList<String>();
for (String fileName : directory.list()) {
if (fileName.endsWith(".mp3")) { songs.add(fileName.trim()); }
}
Collections. sort (songs);
Liste sortieren
for (String song : songs) {
String[] splited = song.split("\\s+-\\s+");
Liste durchlaufen
if (splited.length >= 2) {
System.out.println("Interpret : "+splited[0]+"\n\tTitel: "+ splited[1]);
} else {
System.out.println(song);
}
}
}
}
Seite 10
Th Letschert
<<interface>>
Kollektionen: Liste
List
<<realize>>
java.util.List,
java.util.ArrayList,
<<realize>>
ArrayList
java.util.LinkedList
LinkedList
...
List<Integer> l = new Liste();
List<Integer>();
...
ein Interface hat keine
Objekte!
...
List<Integer> l = null;
l = new ArrayList<Integer>();
l = new LinkedList<Integer>();
...
eine Variable mit
Interface-Typ kann mit
allen passenden
Implementierungen
belegt werden
public void m(List<Integer> l){
... l. listMethode ...
}
...
m( new ArrayList<Integer>() );
...
m( new LinkedList<Integer>() );
...
eine Methode mit
Parameter mit InterfaceTyp kann mit allen
passenden ParameterImplementierungen
umgehen
Seite 11
Th Letschert
<<interface>>
Kollektionen: Liste
List
<<realize>>
java.util.List<E>
<<realize>>
ArrayList
generischer ADT Liste
Verwendung
LinkedList
Datentyp mit Listeneigenschaft-Eigenschaft:
linear sortierte Folge mit Sortierung unter der
Kontrolle der Anwendung
Liste:
Konzept /
ADT-Sicht
1)
2)
3)
4)
5)
6)
A
B
C
D
K
L
java.util
Interface List<E>
Liste: Benutzer-kontrollierte Folge
von Elementen: Die Position von x
in einem List-Typ hängt davon ab,
wohin die Anwendung es
positioniert.
Seite 12
Th Letschert
<<interface>>
Kollektionen: Liste
List
<<realize>>
java.util.ArrayList<E>
<<realize>>
ArrayList
ist die Array-Implementierung (Datenstruktur
Feld/Array) eines generischen ADT Liste
LinkedList
Verwendung
Datentyp mit Listeneigenschaft-Eigenschaft:
linear sortierte Folge mit Sortierung unter der
Kontrolle der Anwendung
Datenstruktur Array:
schnelles indiziertes Zugreifen,
kompakte Speicherung
Einfügen nicht häufig
1)
2)
3)
4)
Liste
Konzept /
5)
ADT-Sicht 6)
A
B
C
D
K
L
Liste
Datenstruktur-Sicht:
Array-Implementierung
Seite 13
java.util
Class ArrayList<E>
LinkedList wenn oft
indiziert zugegriffen und
selten eingefügt / entfernt
wird.
A B C D K L
Th Letschert
<<interface>>
Kollektionen: Liste
List
<<realize>>
java.util.LinkedList<E>
<<realize>>
ArrayList
ist die Zeiger-Implementierung (Datenstruktur
verkettete Liste) eines generischen ADT Liste
LinkedList
Verwendung
Datentyp mit Listeneigenschaft-Eigenschaft:
linear sortierte Folge mit Sortierung unter der
Kontrolle der Anwendung
Datenstruktur verkettete Liste:
schnelles Einfügen / Entfernen an beliebigen
Positionen
1)
2)
3)
4)
Liste
5)
Konzept /
ADT-Sicht 6)
A
B
C
D
K
L
java.util
Class LinkedList<E>
LinkedList wenn oft
eingefügt / entfernt und
selten indiziert
zugegriffen wird.
A
B
C
D
K
L
Liste
Datenstruktur-Sicht:
Implementierung
als verkettete Liste
Seite 14
Th Letschert
Kollektionen: List, ArrayList und LinkerdList
ArrayList
Array-basierte Listenimplementierung
schneller Zugriff / weniger
Speicherbedarf
aufwendiges Einfügen / Entnehmen
(Umkopieren, eventuell neu anlegen)
List-Interface
ArrayList
LinkedList
Durch Referenzen verkettete
Elemente
Zugriff langsam / mehr Speicherplatz
Einfügen / Entnehmen schnell
List-Interface
LinkedList
Seite 15
Th Letschert
Kollektionen: Abbildung (Map)
<<interface>>
Map
<<realize>>
<<realize>>
java.util.Map<K,V>
TreeMap
generischer ADT Abbildung
HashMap
Beispiel:
HashMap<String, Integer> map
= new HashMap<String, Integer>();
//Werte eintragen
map.put("Peter", 4711);
map.put("Inge", 8150);
map.put("Klaus", 2222);
java.util
Interface Map<K,V>
//Wert zu eine Schluessel
System.out.println(
"Klaus hat die Nr: "
+ map.get("Klaus")
);
Seite 16
Th Letschert
Kollektionen: Abbildung (Map)
File directory = chooseFile("Verzeichnis mit Musik");
Map<String, List<String>> songDirectory = new HashMap<String, List<String>>();
for (String fileName : directory.list()) {
if (fileName.endsWith(".mp3")) {
int iDot = fileName.lastIndexOf('.');
fileName = fileName.substring(0, iDot);
Abb: Interpret ~> Liste der Titel
String[] splited = fileName.trim().split("\\s+-\\s+");
String interpret = null;
String titel = null;
if (splited.length >= 2) {
interpret = splited[0];
titel = splited[1];
for (int i = 2; i < splited.length; i++) {
titel = splited[1] + splited[i];
}
} else {
interpret = "Unbekannt";
titel = fileName.trim();
}
List<String> songs = songDirectory.get(interpret);
if (songs == null) {
songs = new LinkedList<String>();
Liste der Titel von interpret
songDirectory.put(interpret, songs);
}
}
}
songs.add(titel);
songDirectory.put(interpret, songs);
for (String i : songDirectory.keySet()) {
System.out.println("Interpret : " + i);
for (String t : songDirectory.get(i)) {
System.out.println("\t" + t);
}
}
Menge der Schlüssel der Abb.
(die Interpreten)
Beispiel: MP3-Dateien in einem
Verzeichnis sortiert nach
Interpret ausgeben
Seite 17
Th Letschert
Kollektionen: Abbildung (Map)
<<interface>>
Map
<<realize>>
<<realize>>
java.util.TreeMap<K,V>
TreeMap
ist die Baum-Implementierung (Datenstruktur
Baum) eines generischen ADT Abbildung
HashMap
Verwendung
Datentyp mit Abbildungstyp-Eigenschaft:
Abbildung von K-Objekten auf V-Objekte
(Key, → Value)
z.B. Name (String) → Telefonnummer (Integer)
Datenstruktur Baum:
➢ schnelles Einfügen und Suchen
➢ sortierte Steicherung
Abbildung:
Konzept /
ADT-Sicht
A
B
C
D
K
L
→
→
→
→
→
→
X
Y
Z
U
V
W
java.util
Class TreeMap<K,V>
C
Z
K
V
A
X
Abbildung,
Datenstruktur-Sicht:
BaumImplementierung
Seite 18
B
Y
D
U
L
W
Th Letschert
Kollektionen: Abbildung (Map)
<<interface>>
Map
<<realize>>
<<realize>>
java.util.HashMap<K,V>
TreeMap
ist die Hash-Implementierung (Datenstruktur
Hash-Tabelle) eines generischen ADT
Abbildung
Verwendung
Datentyp mit Abbildungstyp-Eigenschaft:
HashMap
Abbildung von K-Objekten auf V-Objekte
(Key, → Value)
z.B. Name (String) → Telefonnummer (Integer)
java.util
Class HashMap<K,V>
Datenstruktur Hash-Tabelle:
schnelles Einfügen und Suchen
Abbildung:
Konzept /
ADT-Sicht
A
B
C
D
K
L
→
→
→
→
→
→
X
Y
Z
U
V
W
HashCode der
Keys
Abbildung,
datsnstrutur-Sicht:
Hash-TabellenImplementierung
Seite 19
D
U
C
Z
01
02
03
04
K
V
A
X
B
Y
Th Letschert
L
W
Kollektionen: Menge (Set)
<<interface>>
Set
<<realize>>
<<realize>>
java.util.Set<E>
TreeSet
generischer ADT Menge
(keine Duplikate, Verzicht auf Benutzer-gesteuerte
Reihenfolge der Elemente)
HashSet
Beispiel:
Set<Integer> primZahlen = new TreeSet<Integer>();
Scanner scan = new Scanner(System.in);
java.util
Interface Set<E>
for (int i = 0; i < 10; i++) {
Integer z = scan.nextInt();
if (prim(z)) {
primZahlen.add(z);
A C
K D L
B
}
}
Sets nimmt man nicht nur, wenn man Mengen benötigt, sondern
auch, wenn Dinge sortiert aufbewahrt werden sollen, ihre
Sortierung aber rein intern sein kann. D.h. wenn für die
Anwendung die Art (Reihenfolge) der Speicherung nicht
interessant ist und die Implementierung darum nach eigenen
Vorstellungen speichern darf. Das macht eventuell ein sehr
effizientes (weil von der Bibliothek implementiertes) Suchen und
Einfügen möglich.
Seite 20
Menge:
Konzept /
ADT-Sicht
Th Letschert
Kollektionen: Menge (Set)
<<interface>>
Set
<<realize>>
<<realize>>
java.util.TreeSet<E>
TreeSet
ist die Baum-Implementierung (Datenstruktur
Baum) eines generischen ADT Menge
(~ BaumMenge von oben)
HashSet
Verwendung
Datentyp mit Mengen-Eigenschaft (keine Duplikate)
Verwendung einer Menge statt Liste:
java.util
mit interner Sortierung
Class TreeSet<E>
schnelles Suchen
C
K
A
Menge:
Konzept /
ADT-Sicht
A C
K D L
B
Menge,
Datenstruktur-Sicht:
BaumImplementierung
Seite 21
B
D
L
Th Letschert
Kollektionen: Menge (Set)
<<interface>>
Set
<<realize>>
<<realize>>
java.util.HashSet<E>
ist die Hash-Implementierung (Datenstruktur
Hash-Tabelle) eines generischen ADT
Menge
Verwendung
Datentyp mit Mengen-Eigenschaft
Datenstruktur Hash-Tabelle:
schnelles Einfügen, Entfernen und Suchen
keine interne Sortierung
HashCode der
Elemente
Menge:
Konzept /
ADT-Sicht
A C
K D L
B
Menge
Datenstruktur-Sicht:
Hash-TabellenImplementierung
Seite 22
TreeSet
HashSet
java.util
Class HashSet<E>
D
C
01
02
03
04
K
A
L
B
Th Letschert
Helferklasse Collections
Collections
Helfer-Klasse aus java.util
arbeitet auf Kollektionen (z.B. ArrayList)
vergleichbar mit
der Klasse Arrays für Felder
List<Integer> l = new ArrayList<Integer>();
... l fuellen ...
// l sortieren:
Collections.sort(l);
// l ausgeben:
System.out.println(a.toString());
Seite 23
Th Letschert
Helferklasse Arrays
Arrays
●
●
Helfer-Klasse aus java.util mit statischen Methoden
ist kein Array !
Collections
●
●
Helfer-Klasse aus java.util mit statischen Methoden
ist keine Kollektion !
Collection
●
Basis-Interface für List und Set
Kollektion, Kollektions-Typen
●
●
●
●
Kollektion, Collection: Sammelbegriff für vordefinierte
Klassen der Bibliothek
Alternativen zu array
definiert im Paket java.util
Beispiel einner Kollektionsklasse: ArrayList
Seite 24
Th Letschert
Collections Framework: Übersicht
Framework (Rahmen): System
vorgegebener Definitionen in
die eigene Implementierungen
eingepasst werden.
aus http://java.sun.com/javase/6/docs/technotes/guides/collections/overview.html
Die Interfaces Set / List / Map / ...
beschreiben Funktionalitäten, die auf
unterschiedliche Art in Klassen
implementiert sind.
Collection
Set
...
Map
List
ArrayList
LinkedList
Seite 25
...
LinkedHashMap
...
Th Letschert
Collections Framework: Namenskonvention
Namenskonvention:
Implementierungs-Art Implementiertes Interface
Beispiele:
ArrayList
LinkedList
HashMap
TreeMap
HashSet
TreeSet
Seite 26
Th Letschert
Collections: Referenz-Semantik
In einer Kollektion werden stets nur
Referenzen gespeichert
ArrayList<Integer> l = new ArrayList<Integer>();
l.add( 128 );
l.add( 128 );
l
if ( l.get(0) == l.get(1) )
System.out.println( l.get(0)+" = "+l.get(1) );
else
System.out.println( l.get(0)+" != "+l.get(1) );
if ( l.get(0).equals(l.get(1)) )
System.out.println( l.get(0)+" equals "+l.get(1) );
else
System.out.println( l.get(0)+" !equals "+l.get(1) );
Ausgabe:
Seite 27
null
128
128
128 != 128
128 equals 128
Th Letschert
Generische und nicht generische Kollektionen
generische Kollektion
keine primitiven Typen hier!
(ab Java 5)
Kollektion mit
festgelegtem ElementTyp.
Element-Typ nicht
primitiv!
nicht generische
Kollektion
Element-Typ wird nicht
explizit angegeben
Kollektion kann
Elemente
unterschiedlichen Typs
aufnehmen.
Keine primitiven Typen
in Kollektionen!
ArrayList<Integer> l
= new ArrayList<Integer>();
l.add(1);
l.add("Hallo");
ArrayList l
= new ArrayList();
l.add(1);
//l.add(new Integer(1));
l.add("Hallo");
Autoboxing: automatische
Konversion
int => Integer
Im Normalfall (kein Typenmix) generische
Kollektionen verwenden!
Seite 28
Th Letschert
Nun, wer hat denn
brav sein equals
implementiert ?
Kollektionen:
Anforderungen an die
Elemente
Seite 29
Th Letschert
Hashing
Hashing: Methode zur Speicherung von
Zuordnungen: Schlüssel → Wert
Das Hashverfahren beruht auf einer
Schlüsseltransformation. Dem Schlüssel
(beliebiges Objekt) wird dabei eine Schlüsselwert
(int-Wert) zugeordnet
Die Speicheradresse eines Datensatzes wird
ohne zusätzliche Hilfsstrukturen aus dem
Schlüsselwert berechnet. (Beispielsweise als
Index in einem Array, der Hashtabelle.)
Die Beziehung zwischen Schlüsselwert und
Speicheradresse wird durch eine Hashfunktion
hergestellt.
Die Anwendung dieser Funktion auf den
Schlüsselwert ergibt die Speicheradresse
Seite 30
java.util
Class HashMap<K,V>
java.util
Class HashSet<E>
''Hallo''
=> hash(''Hallo'') = 4711
=> hashTable[4711] -> ''Hallo''
Th Letschert
Hashing: Anforderungen an die Element-Typen
java.util.HashSet<E>
java.util.HashMap<K,V>
E bzw. K sollten die Methode equals
implementieren
E bzw. K sollten die Methode hashCode
implementieren
beide Methoden sollten verträglich sein:
x.equals(y) =>
x.hashCode() ==
y.hashCode()
gleiche Elemente haben den gleichen
Hash-Code
java.util
Class HashMap<K,V>
java.util
Class HashSet<E>
siehe API-Doku zu java.lang Interface Comparable<T>:
It is strongly recommended (though not required) that natural orderings be consistent
with equals. This is so because sorted sets (and sorted maps) without explicit
comparators behave "strangely" when they are used with elements (or keys) whose
natural ordering is inconsistent with equals. In particular, such a sorted set (or sorted
map) violates the general contract for set (or map), which is defined in terms of the
equals method.
Seite 31
Th Letschert
Hashing: Anforderungen an die Element-Typen
Definition einer hashCode-Methode
Der Hashcode eines Objekts darf nur von den für equals relevanten
Objektvariablen beeinflusst werden
Objekte die gleich sind (entspr. equals) müssen den gleichen hash-Code liefern
Der Hashcode eines Objekts kann beispielsweise wie folgt berechnet werden:
●
Berechne den Hashcode jeder relevanten Objektvariablen f wie folgt:
➢
➢
➢
➢
➢
➢
➢
●
boolean f => (f ? 1 : 0)
byte f, int f, short f => (int) f
long f => f^(f>>>32))
float f => Float.floatToBits(f)
double f => Double.doubleToLongBits(f)^(Double.doubleToLongBits(f)>>>32)
AClass f => (f == 0 ? 0 : f.hashCode())
Atype[] f => Verfahre mit den Elementen wie mit Objektvariablen
Berechne den Hashcode des Objekts aus dem seiner Felder mit
int res = 1
für jeden Hashcode c eines Felds
res = 31 * res + c Seite 32
Th Letschert
equals / hashcode
Wer equals sagt, der
muss auch
hashCode sagen!
public class Person {
private String vorName;
private String nachName;
public Person(String vorName, String nachName){
this.vorName = vorName;
this.nachName = nachName;
}
public String toString(){
return vorName+" "+nachName;
}
public boolean equals(Object o){
if ( !(o instanceof Person) )
return false;
Person p = (Person)o;
if (vorName.equals(p.vorName)
&& nachName.equals(p.nachName))
return true;
else return false;
}
public int hashCode(){
return 31*vorName.hashCode()
+nachName.hashCode();
}
}
Seite 33
Selbst definierte
Klassen, die als
Schlüssel (Key) einer
HashMap oder
Element eines HashSet
auftreten, sollen equals
und hashCode
konsistent definieren.
Vordefinierte Klassen
von Java erfüllen diese
Anforderung.
Th Letschert
Trees: Anforderungen an die Element-Typen
java.util.TreeSet<E>
java.util.TreeMap<K,V>
E bzw. K sollte die Schnittstelle
Comparable implementieren
damit ein sortierter Suchbaum aufgebaut
werden kann
die Methode equals von E bzw. K sollte
dazu passen
x.equals(y) <=>
x.compareTo(y) == 0
was gleich ist, sollte die gleiche
Ordnungsposition haben und
umgekehrt
Seite 34
java.util
Class TreeSet<E>
java.util
Class TreeMap<K,E>
Th Letschert
Vergleichbarkeit
java.lang
interface Comparable<T>
int compareTo(T o)
allgemeine Vergleichbarkeit
x.compareTo(y) < 0
x.compareTo(y) = 0
x.compareTo(y) > 0
x < y
x == y
x > y
<, >, == ist nur auf wenigen primitiven Typen definiert.
Instanzen von Klassen werden mit compareTo verglichen.
Diese Methode ist auf Klassen Standard-Klassen wie Integer, String, ... vordefiniert.
Eine Klasse erklärt, dass ihre Objekte vergleichbar, sind sie also compareTo zur
Verfügung stellt, indem sie die Schnittstelle Comparable implementiert.
z.B:
class C implements Comparable<C> {
...
int compareTo(C c) { ... }
...
}
Seite 35
Th Letschert
Übersicht: Anforderungen an die Element-Typen
java.util.ArrayList<E>
E sollte die Methode equals implementieren
java.util.LinkedList<E>
E sollte die Methode equals implementieren
java.util.TreeSet<E>
E sollte die Schnittstelle Comparable implementieren die Methode
equals sollte dazu passen
java.util.HashSet<E>
E sollte die Methoden equals und dazu passend hashCode
implementieren
java.util.TreeMap<K,V>
K sollte die Schnittstelle Comparable implementieren die Methode
equals sollte dazu passen
java.util.HashMap<K,V>
K sollte die Methoden equals und dazu passend hashCode
implementieren
Seite 36
Th Letschert
equals / compareTo : Beispiel 1
public class Person implements Comparable<Person> {
private String vorName;
private String nachName;
public Person(String vorName, String nachName) {
this.vorName = vorName; this.nachName = nachName;
}
public String toString() {return vorName + " " + nachName;
}
public boolean equals(Object o) {
if (!(o instanceof Person))
return false;
Person p = (Person) o;
if (vorName.equals(p.vorName) && nachName.equals(p.nachName))
return true;
else
return false;
}
public int compareTo(Person p) {
return nachName.compareTo(p.nachName) != 0 ?
nachName.compareTo(p.nachName)
: vorName.compareTo(p.vorName);
}
public static void main(String[] args) {
TreeSet<Person> s = new TreeSet<Person>();
s.add(new Person("Minni", "Maus"));
s.add(new Person("Peter", "Pan"));
s.add(new Person("Micky", "Maus"));
s.add(new Person("Charly", "Brown"));
for ( Person p : s)
System.out.println(p);
}
}
Seite 37
Selbst definierte
Klassen, die als
Element einer sortierten
Menge (TreeSet) oder
als Schlüssel einer
sortierten Abbildung
(TreeMap) auftreten,
sollen equals und
compareTo konsistent
definieren.
Vordefinierte Klassen
von Java erfüllen diese
Anforderung.
Selbst geschriebene
Klassen sollten sie auch
erfüllen!
36
Th Letschert
equals / compareTo / hashCode : Beispiel 2 (1)
/**
* Zweidimensionale Vektoren.
* Ein Objekt dieser Klasse realisiert einen Vektor in der Ebene in karthesischer Darstellung.
*
* Achtung: Diese Klasse hat eine natuerliche Ordung die nicht konsistent ist mit equals!
* Note: This class has a natural ordering that is inconsistent with equals!
*/
final class VektorK_A implements Comparable<VektorK_A> {
private double x;
private double y;
public VektorK_A(double x, double y) { this.x = x; this.y = y; }
public double length() { return Math.sqrt(x*x + y*y); }
// toString wird eigentlich immer definiert!
public String toString(){ return "<" + this.x + ", " + this.y + ">"; }
@Override
public int compareTo(VektorK_A v) { return (int) (this.length() - v.length()); }
public boolean equals(VektorK_A v) { return x == v.x && y == v.y; }
public boolean equals(Object o) {
if (o instanceof VektorK_A) {
return this.equals((VektorK_A) o);
} else {
return false;
}
}
equals und compareTo sollten consistent
sein. Sie müssen aber nicht.
Seite 38
Th Letschert
equals / compareTo / hashCode :Beispiel 2 (2)
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
* Einfaches Muster fuer hashCode:
* Verarbeite den Hashcode jedes Feldes (= Objektvariale), das bei
* Gleichheit eine Rolle spielt
* (und NUR DIESE! Gleiches muss den gleichen Hashcode liefern).
* Handelt es sich um einen primitiven Typ, dann nimm eine
* Hilfsroutine wie Double.doubleToLongBits
*/
@Override
public int hashCode() {
final int prime = 31;
long hash = 1;
hash = hash * prime + Double.doubleToLongBits(x) % Integer.MAX_VALUE;
hash = hash * prime + Double.doubleToLongBits(y) % Integer.MAX_VALUE;
return (int) hash;
}
...
}
Seite 39
Th Letschert
Kollektion
Iterator
Iteratoren
Seite 40
Th Letschert
Iterator
Iterator
Mechanismus zum Durchlaufen einer
Kollektion
explizite Nutzung
implizite Nutzung mit foreach-Schleife
ArrayList<Integer> l =
new ArrayList<Integer>();
l.add(1); l.add(2); l.add(3);
iterierbare Kollektion
oder Feld
for ( int i : l )
System.out.println(i);
implizite Nutzung eines Iterators
Iterator<Integer> iter =
l.iterator();
while ( iter.hasNext() ) {
System.out.println( iter.next() );
}
explizite Nutzung eines Iterators
Seite 41
Th Letschert
Iteratoren und das Collections-Framwork
Java—Kollektionen sind iterierbar
sie können Iteratoren erzeugen
mit dem man sie durchlaufen kann
public interface Collection<E> extends
Iterable<E>{...}
public interface List<E> extends Collection<E>{...}
public class ArrayList<E>extends AbstractList<E>
implements List<E>,RandomAccess, Cloneable, Serializable {...}
Iterable
Iterable
<<realize>>
Collection
iterator():Iterator
iterator():Iterator
Iterator
Iterator
next():Object
next():Object
hasNext():boolean
hasNext():boolean
...
Map
List
Set
<<use>>
ArrayList
iterierbar
Seite 42
LinkedList
...
LinkedHashMap
nicht iterierbar
Th Letschert
Iteratoren und das Collections-Framwork
Java—Kollektionen sind iterierbar
Iterable : sie können Iteratoren erzeugen: Methode iterator ~> Iterator
Iterator : mit dem man sie durchlaufen kann hasNext / next
ArrayList<Integer> l =
Iterator
Iterator
new ArrayList<Integer>();
next():Object
next():Object
hasNext():boolean
hasNext():boolean
l.add(1); l.add(2); l.add(3);
Iterator<Integer> iter =
l.iterator();
<<use>>
Iterable
Iterable
Collection
iterator():Iterator
iterator():Iterator
List
<<realize>>
<<realize>>
while ( iter.hasNext() ) {
System.out.println( iter.next() );
}
automatische
Umwandlung durch
den Compiler
for ( int i : l )
System.out.println(i);
ArrayList
Seite 43
Th Letschert
Iteratoren und das Collections-Framwork
Listen
java.util.ArrayList<E>
java.util.LinkedList<E>
iterierbar mit Iterator
Iterator<E> iterator()
iterierbar mit Listen-Iterator (Durchlauf in beide Richtungen)
ListIterator<E> listIterator()
Mengen
java.util.TreeSet<E>
java.util.HashSet<E>
iterierbar mit Iterator
Iterator<E> iterator()
Abbildungen
java.util.TreeMap<K,V>
java.util.HashMap<K,V>
nicht iterierbar
aber
Set<K> keySet() liefert die (iterierbare) Menge der Schlüssel
Seite 44
Th Letschert
Collections-Framwork verwenden
Schnittstelle auswählen
Implementierungsvariante (Datenstruktur) auswählen
Anforderungen an Elementtypen prüfen / erfüllen
Seite 45
Th Letschert
Herunterladen