Kapitel 7

Werbung
7. Kapitel
COLLECTIONS
Techniken der Programmentwicklung
Prof. Dr. Wolfgang Schramm
Übersicht
1
1. Programmstrukturierung mit Paketen (packages)
2. Vererbung
3. Abstrakte Klassen und Interfaces
4. Ausnahmebehandlungg
5. Datenströme: die Java IO‐Bibliothek
6. Multithreading
7. Collections
8 Innere Klassen
8.
Innere Klassen
9. Generics
10 Reflection
10.
Lernziele des Kapitels
2




Kennenlernen des Java Collection API.
Die wichtigsten Collections und ihre Eigenschaften näher kennenlernen.
Collections einsetzen können.
Iteratoren kennen‐ und einsetzen lernen.
i
l
Inhalt
3

Einführung, Motivation
 Collection


Definition

Eigenschaften
Die Collection‐Historie

Die „ganz alten“ Collections (seit Java 1)



Vector
HashTable
Das Collection Framework (ab Java 5)

Eigenschaften

Entwurfsprinzipien

Aufbau
 Auswahl einiger wichtiger Collections




Map
Set
List
Iteratoren
Collection ‐ Begriff
4

Collections/ Container = Datenstrukturen, die dazu dienen, Mengen von Daten aufzunehmen und zu verarbeiten.

Die Daten werden gekapselt abgelegt, und der Zugriff ist nur mit Hilfe vorgegebener Methoden möglich.

Haben wir als ADTs schon in ADS kennengelernt.

Typische Collections: Stacks, Queues, Hashtabellen, Listen und Trees.

Äquivalenz Collections für Datenstrukturen = Schleifenkonstrukte für Anweisungen.


Schleifen: die Wiederholbarkeit und Wiederverwendbarkeit von Code Collections: Zusammenfassung und repetitive Bearbeitung von einzelnen Datenelementen. 
Verwendung von Collections: oft im Zusammenhang mit Schleifen, z.B. wenn das Programm von seiner Struktur her nicht Einzel‐, sondern Mengendaten verarbeitet. 
Hauptrolle von Collections: Elementardaten zu speichern und einen der Bearbeitung angemessenen Zugriff darauf zu ermöglichen.

Collections können ganz neue Sichten auf die Daten definieren. Eine Hashtable
beispielsweise stellt Daten paarweise zusammen und ermöglicht so die Definition einer
beispielsweise stellt Daten paarweise zusammen und ermöglicht so die Definition einer Referenzbeziehung, die ohne ihre Hilfe nur schwer herzustellen wäre. 
Collections in einfachen Programmiersprachen: meist nur in Form von Arrays.

In Java und anderen objektorientierten Sprachen: ganze Reihe unterschiedlicher Collections
In
Java und anderen objektorientierten Sprachen: ganze Reihe unterschiedlicher Collections
(als ADTs) mit einem viel breiter gefächerten Aufgabenspektrum. Motivation: mehr Flexibilität durch geschickte Organisation der ADTs
Organisation der ADTs
5

Ziel: Die gespeicherten Daten sollen unabhängig von der Implementierung (der konkreten Datenstruktur) immer mit derselben Technik abgefragt werden können
Datenstruktur) immer mit derselben Technik abgefragt werden können.

Um welche Datenstrukturen handelt es sich meistens: Arrays, Bäume etc.

Welche Operationen werden gebraucht? 

Suche: Frage nach der Zugehörigkeit eines Werts zum Datenbestand, also: »Gehört das Wort dazu?«. (Wortproblem)

Aufzählung der Daten in irgendeiner Weise.
Wie können die Operationen realisiert werden?

Arrays: Zugriff auf die Elemente über den Index.

Aber: nicht immer ein Array der Datenspeicher und die objektorientierte Programmierung verbietet, Aber:
nicht immer ein Array der Datenspeicher und die objektorientierte Programmierung verbietet,
hinter die Kulisse zu sehen  allgemeinerer Weg des Zugriffs über sog. Iteratoren.

Dafür gibt es 2 unterschiedliche Interfaces:
 Enumeration.
Enumeration
 Iterator.
Operationen auf Collections
6



Basisoperationen zum Erfragen der Elementanzahl und zum Hinzufügen, Löschen, Selektieren und Finden von Elementen.
f
h
l k
l
Mengenoperationen, um etwa andere Collections
einzufügen.
i fü
Feldoperationen bei Collection, um die Sammlung in ein Array zu konvertieren und bei Map Operationen, um Array zu konvertieren, und bei Map
Operationen um
alternative Sichten auf Schlüssel oder Werte zu bekommen.
Die Klasse Vector
7

Die Klasse Vector implementiert ein dynamisches Array, das 
Objekte speichern kann. b k
h
k
Die Größe des Vektors wird automatisch an die benötigte G öß
Größe angepasst, d.h. die Größe ist zur Laufzeit veränderbar.
t d h di G öß i t
L f it ä d b

Elemente können an beliebiger Stelle eingefügt werden.

Der Zugriff auf die Elemente: sowohl sequentiell als auch wahlfrei
Der Zugriff auf die Elemente: sowohl sequentiell als auch wahlfrei.

Die Zugriffe auf vorhandene Elemente und das Durchlaufen des Vector sind schnelle Operationen.

Einfügungen und Löschungen , welche die interne Kapazität des Arrays über‐ bzw. unterschreiten, sind relativ langsam, weil Teile des Arrays p
umkopiert werden müssen.

Die Zugriffsoperationen sind sicher.
Methoden der Klasse Vector (Auswahl)
8
public Vector()
// voreingestellte Kapazität von 10 Elementen
public Vector(int initialCapacity)
public Vector(int initialCapacity, int capacityIncrement)
public Vector(Collection c)
j
java.util.Vector
til V t
public final boolean isEmpty()
public final int size()
public void addElement(Object obj)
public void insertElementAt(Obj obj, int index) throws
ArrayIndexOutOfBoundsException
public Object firstElement() throws NoSuchElementException
public Object lastElement() throws
NoSuchElementException
public Object elementAt(int index) throws
public Enumeration elements()
ArrayIndexOutOfBoundsException
Iterieren über Vector
9

public boolean hasMoreElements()
public Object
p
j nextElement() throws
()
NoSuchElementException
p

public Enumeration elements() // aus java.util.Vector
p
() //
j

java.util.Enumeration
Achtung: Uralttechnik!
public class MyVector {
public static void main(String[] args) {
Vector v = new Vector();
Besser: Iterator verwenden.
v.addElement("eins");
v addElement("drei");
v.addElement(
drei );
v.insertElementAt("zwei",1);
for (Enumeration el = v.elements(); el.hasMoreElements(); )
System.out.println((String)el.nextElement());
}
}
Methoden der Klasse Stack
10
class Stack extends Vector
public
public
public
public
p
public
Object push(Object item)
Object pop()
Object peek()
boolean empty()
p y()
int search(Object o)
java.util.Stack
Die Klasse Hashtable – Konkretisierung der Klasse Dictionary
11








Konkretisierung der abstrakten Klasse Dictionary.
Dictionary speichert immer zusammengehörige Paare von Schlüsseln und Daten speichert immer zusammengehörige Paare von Schlüsseln und Daten
(assoziativer Speicher).
Der Schlüssel wird als Name des zugehörigen Wertes angesehen.
Üb d S hlü l k
Über den Schlüssel kann später der Wert wieder gefunden werden. ä d W
i d
f d
d
Über den Schlüsselbegriff wird ein effizienter Zugriff auf den Wert ermöglicht.
Ein Dictionary kann auf unterschiedliche Weise implementiert werden.
Die Implementierung Hashtable benutzt das Verfahren der Schlüsseltransformation, also die Verwendung einer Transformationsfunktion (Hash‐Funktion), zur Abbildung von Schlüsseln auf Indexpositionen eines Arrays.
Weitere Konkretisierungen der Klasse Dictionary, etwa auf der Basis binärer Bäume, gibt es in Java derzeit nicht.
Methoden der Klasse Hashtable (Auswahl)
12
public Hashtable()
java.util.Hashtable
public Hashtable (int initialCapacity)
public void clear()
public boolean contains (Object value)
public boolean containsKey (Object key)
public boolean containsValue (Object value)
public Enumeration elements ()
public Object get (Object key)
public Object put (Object key, Object value)
Iterieren über Hashtable
13
public class MyHash {
p
public static void main(String[] args) {
Hashtable h = new Hashtable();
//Pflege der Aliase
h.put("Fritz","[email protected]");
h.put("Alex","[email protected]");
al@bla lrbla.com
h put("Sven"
h.put(
Sven ,"s
s.klaus@hs
klaus@hs-mannheim
mannheim.de
de");
); Alex --> [email protected]
h.put("Claudia","[email protected]"); Claudia --> [email protected]
Sven --> [email protected]
//Ausgabe
Fritz
i
--> [email protected]
f
ll @
i d
Enumeration e = h.keys();
while (e.hasMoreElements()) {
String alias = (String)e.nextElement();
System.out.println(alias + " --> " + h.get(alias));
}
}
}
Entwurfsziele für das Collection API (von Java 5)
15




Das API soll vernüftig klein sein – bezüglich seines Umfangs und seines Konzepts aber mächtig.
und seines Konzepts –
aber mächtig
Die neue Funktionalität soll die alte erweitern, nicht ersetzen, d.h. für den Programmierer soll sich nicht viel ändern.
d.h. für den Programmierer soll sich nicht viel ändern.
Wenige Kern‐Interfaces, die (noch) keine Feinheiten z.B. (variable Größe, Änderbarkeit) festlegen. Um die Anzahl der Methoden in den Kern‐Interfaces gering zu halten, enthält ein Interface eine Methode nur, wenn



Die Operation eine elementare ist, d.h. Elementaroperationen mittels l
dh l
l
derer andere vernünftig beschrieben werden können.
Nur aus zwingenden Performancegründen sollten diese Operationen von einer Implementierung überschrieben werden.
Alle wichtigen Repräsentationen von Collections sollen interoperabel sein
interoperabel sein.
Entwurfsprinzipien des Collection Framworks
16

Schnittstellen legen Gruppen von Operationen für die verschiedenen Behältertypen fest
Behältertypen fest.


Abstrakte Basisklassen führen die Operationen der Schnittstellen auf eine Abstrakte
Basisklassen führen die Operationen der Schnittstellen auf eine
minimale Zahl von als abstrakt deklarierten Grundoperationen zurück.


Beispiele: etwa addAll() auf add() oder isEmpty() auf getSize(). Konkrete Klassen für bestimmte Behältertypen beerben die entsprechende abstrakte Basisklasse und ergänzen die unbedingt erforderlichen Grundoperationen (und einige die Performance steigernde Abkü
Abkürzungen gegenüber der allgemeinen Lösung in der Oberklasse). Sie üb d
ll
i
Lö
i d Ob kl
) Si
sind in der Nutzung unsere direkten Ansprechpartner.


Beispiele: List  Schnittstelle für Sequenzen (Listen), Map  Schnittstelle für Assoziativspeicher, die Schlüssel‐Werte‐Paare verbinden.
Beispiele: Für eine Liste entweder die Klasse ArrayList oder die Klasse Vector und als Assoziativspeicher die Klasse TreeMap.
l A
i ti
i h di Kl
T M
Algorithmen, wie die Suche nach einem Element, gehören zum Teil zur Schnittstelle der Datenstrukturen. Zusätzlich gibt es mit der Klasse C ll i
Collections
eine Utility‐Klasse mit weiteren Algorithmen.
i U ili Kl
i
i
Al i h
Collection‐Framework (seit Java 5)
17


Sammlung von mehr als 40 Klassen und 14 Interfaces im Paket java.util, die das Collections‐Framework des JDK bilden.
Im wesentlichen die fünf Collection‐Grundformen:






Collection Sammlung von Objekten ohne besondere Ordnung, Duplikate sind zulässig
Duplikate sind zulässig.
List ist eine beliebig große Liste von Elementen beliebigen Typs, auf die sowohl wahlfrei als auch sequentiell zugegriffen werden kann. Set ist eine (doublettenlose) ungeordnete Menge von Elementen, auf die mit typischen Mengenoperationen zugegriffen werden kann.
Queue Warteschlange mit speziellen Methoden, die auch mit leeren Q
g
p
,
oder überfüllten Warteschlangen ohne Ausnahmen umgehen können.
Map ist eine Abbildung von Elementen eines Typs auf Elemente eines anderen Typs, also eine Menge zusammengehöriger Paare von
anderen Typs, also eine Menge zusammengehöriger Paare von Objekten. Es werden verschiedene Implementierungsvarianten bereitgestellt – in Form von Interfaces und einiger abstrakter Basisklassen – mit denen die Implementierung Interfaces und einiger abstrakter Basisklassen mit denen die Implementierung
eigener Collections vereinfacht werden kann.
Collection‐Framework
18

Es gibt jeweils eine oder mehrere konkrete Implementierungen zu d 5 (4) ( l I t f
den 5 (4) (als Interface festgelegten) Grundformen.
f t l t ) G df

Sie unterscheiden sich in den verwendeten Datenstrukturen und Algorithmen und damit in ihrer Eignung für verschiedene
Algorithmen und damit in ihrer Eignung für verschiedene Verwendungsarten.

Es gibt eine abstrakte, sog. Rumpfimplementierung des Interfaces, g
g
p p
g
mit dessen Hilfe das Erstellen eigener Collections erleichtert wird.

Schema der Namensgebung der Interfaces und Klassen:

Das Interface hat immer den allgemein verwendeten Namen der zu implementierenden Collection (List, Set, Queue, Map).

Jede Implementierungsvariante stellt vor den Namen dann eine Jede
Implementierungsvariante stellt vor den Namen dann eine
spezifische Bezeichnung. Sie gibt einen Hinweis auf die Art der verwendeten Datenstrukturen und Algorithmen.

Beispiel: Für das Interface List gibt es die Implementierungsvarianten B
i i l Fü d I t f
Li t ibt di I l
ti
i t
LinkedList und ArrayList sowie die abstrakte Implementierung AbstractList. Die wichtigsten Interfaces des Collection Framework
19
Iterable
Collection
Set
SortedSet
NavigableSet
g
Iterator
List
Queue
Deque
BlockingQueue
BlockingDeque
Collections des Typ Map
20
I
I = Interface
K = Klassen
Iterator
Collection
Map
I
SortedMap
Ab t tM
AbstractMap
K
K
K
HashMap
LinkedHash
Map
IdentityHash
Map
PrinterState
Reasons
WeakHash
Map
TreeMap
HashMap ‐ Beispiel
21
import java.util.*;
public class MyHashMap {
public static void main(String[] args) {
HashMap h = new HashMap();
//Pflege der Aliase
h.put("Fritz","[email protected]");
h.put("Alex","[email protected]");
h put("Sven"
h.put(
Sven ,"s
[email protected]
klaus@hs-mannheim de");
);
h.put("Claudia","[email protected]");
//Ausgabe
for (Object o: h.entrySet())
h entrySet()) {
//System.out.println (o);
Map.Entry entry = (Map.Entry)o;
System.out.println(
(St i ) t
(String)entry.getKey()
tK () + " --> " +
(String)entry.getValue());
}
}
}
Quelle: [Krüger]
Sven --> s
[email protected]
klaus@hs-mannheim de
Alex --> [email protected]
Fritz --> [email protected]
Claudia --> [email protected]
Basisinterface Collection
22
Um nicht für jede denkbare Collection‐Klasse ein eigenes Interface definieren zu müssen wurde ein Basisinterface Collection geschaffen aus dem die meisten
müssen, wurde ein Basisinterface Collection geschaffen, aus dem die meisten Interfaces abgeleitet wurden. Es fasst die wesentlichen Eigenschaften einer großen Menge unterschiedlicher Collections zusammen: int size()
java.util.Collection
boolean isEmpty()
boolean contains(Object o)
Iterator iterator()
Object[] toArray()
Object[] toArray(Object[] a)
boolean add(Object o)
boolean remove(Object o)
boolean containsAll(Collection c)
boolean addAll(Collection
(
c)
)
boolean removeAll(Collection c)
boolean retainAll(Collection c)
void clear()
boolean equals(Object o)
int hashCode()
Ändert sich die Zusammensetzung
der Collection  true
Interface Collection
23
Collection
+size (): int
+ isEmpty (): boolean
+ contains (o: Object): boolean
+ iterator (): Iterator
+ toArray (): Object[]
+ toArray (a: Object[]): Object[]
+ add (o: Object): boolean
+ remove (o: Object): boolean
+ containsAll (c: Collection): boolean
+ addAll (c: Collection): boolean
+ removeAll (c: Collection): boolean
+ retainAll (c: Collection): boolean
+ clear (): void
+ equals (o: Object): boolean
+ hashCode (): int
Interface Collection
24

Bis auf die Assoziativspeicher implementieren die Datenstrukturen die Schnittstelle Collection und erhalten damit einen gemeinsamen äußeren
Schnittstelle Collection und erhalten damit einen gemeinsamen, äußeren Rahmen.

Basis‐Operationen für hinzufügen, löschen, selektieren und finden von Elementen.

Die Collection‐Schnittstelle wird von mehreren Schnittstellen erweitert.

Abgeleitete Schnittstellen schreiben Verhalten vor, ob etwa der Container Werte doppelt beinhalten darf oder die Werte sortiert hält; List, Set und SortedSet sind pp
;
,
die wichtigsten.

AbstractCollection implementiert Basisfunktionalität und belässt nur noch zwei abstrakte Funktionen.
abstrakte Funktionen.
Interface Collection: Beispiel
25
import java.util.*;
class ErsteSammlung {
public static void main( String args[] ) {
Collection c = new LinkedList();
for ( int i = 0; i < 10; i++ ) c.add( "" + i );
for ( Iterator it = c.iterator();
c iterator(); it.hasNext();)
it hasNext();)
System.out.println( it.next() );
}
}
Ändern der Implementierung:
Collection c = new LinkedList();  Collection c = new ArrayList();
Collection: Interface List
26

Eine Collection vom Typ List ist eine geordnete Menge von Objekten.

ZZugriff auf Elemente entweder sequentiell oder über ihren Index (ihre Position in iff f El
d
i ll d üb ih
I d (ih P i i i
der Liste) zugegriffen werden kann.

Wie bei Arrays hat das erste Element den Index 0 und das letzte den Index size() ‐
1.

Einfügen/Löschen von Elementen: an einer beliebigen Stelle der Liste. Die weiter hinten stehenden Elemente werden dann entsprechend nach rechts bzw. links p
verschoben.

Des weiteren gibt es Methoden, um Elemente in der Liste zu suchen. 
Das Interface List ist direkt aus dem Interface Collection
D
I t f
Li t i t di kt
d
I t f
C ll ti abgeleitet und erbt somit b l it t d bt
it
dessen Methoden. Zusätzlich gibt es einige neue Methoden, die zum wahlfreien Zugriff auf die Elemente benötigt werden.

Einfügen von Elementen: add und addAll.
Interface List – Methoden (Auswahl)
27
void add(int index, Object element)
boolean add(Object o)
boolean addAll(Collection c)
boolean addAll(int index, Collection c)
Object remove(int index)
boolean remove(Object o)
boolean removeAll(Collection c)
boolean retainAll(Collection c)
Ändert sich die Zusammensetzung
der Liste  true
Collections des Typ List
28
I
Collection
I
Li t
List
K
Abstract
Collection
K
I = Interface
K = Klassen
Abstract
List
K
ArrayList
Iterator
Abstract
Sequential List
Vector
LinkedList
Stack
K
Beispiel – List(en)
29
import java.util.*;
public class MyList {
static void fillList(List list) {
for (int i = 0; i < 10; ++i) {
list.add("" + i);
}
list.remove(3);
list.remove("5");
}
static void printList(List list) {
for (
(int i = 0;
; i < list.size();
(); ++i)
) {
System.out.println((String)list.get(i));
}
}
System.out.println("---");
}
Quelle: [Krüger]
public static void main(String[] args) {
//Erzeugen
g
der LinkedList
LinkedList list1 = new LinkedList();
fillList(list1);
printList(list1);
//Erzeugen der ArrayList
ArrayList list2 = new ArrayList();
fillList(list2);
printList(list2);
//Test von removeAll
list2.remove("0");
list1.removeAll(list2);
printList(list1);
}
0
1
2
4
6
7
8
9
---
0
1
2
4
6
7
8
9
---
0
---
Schnittstelle Iterator
30
Iteration bei herkömmlichen Datenstruktur‐Klassen (und bis JDK 1.2):
Enumeration (hasMoreElements(), nextElement()).
Mit dem neuen Collection‐Framework (seit JDK 1.2):
Iterator (hasNext(), next (), remove()).
Ein Iterator kann die aufgezählte Datenstruktur grundsätzlich verändern (remove), eine
Enumeration nicht.
Bei allen Collections, die das Interface Collection implementieren, kann ein Iterator zum
Durchlaufen aller Elemente mit der Methode iterator beschafft werden.
Iterator
+ hasNext(): boolean
+ next(): Object
+ remove(): void
Iterator ‐ Beispiel
31
import java.util.*;
2
public class MyIterator {
public static void main(String[] args) {
// Füllen der Liste
ArrayList list = new ArrayList();
for (int i = 1; i <= 20; ++i) {
list.add("" + i);
}
// Löschen von Elementen über Iterator
Iterator it = list.iterator();
while (it.hasNext()) {
String
g s = (String)
g it.next();
if (s.startsWith("1"))it.remove();
}
//Ausgeben der verbleibenden Elemente
it = list.iterator();
();
while (it.hasNext())
System.out.println((String) it.next());
}
}
Quelle: [Krüger]
3
4
5
6
7
8
9
20
Erweiterte for‐Schleife
32
Iterieren mit einem Iterator mit der for‐Schleife:
for (Iterator it = ausdruck.iterator(); it.hasNext(); ){
formalerparameter = it.next();
anweisung;
}
Iterieren mit der äquivalenten, erweiterten for‐Schleife:
f
for
(f
(formalerparameter
l
t
: ausdruck
d
k ) anweisung;
i
formalerparameter = aus Datentyp und Variablenname bestehende Parameterdeklaration der Art Integer i oder Object o ausdruck = Instanz oder ein Ausdruck des Typs java.lang.Iterable oder ein Array.
Erweiterte for‐Schleife ‐ Beispiel
33
import java.util.*;
public static void printVector2(Vector v) {
for (Object
j
o : v)
System.out.println(o);
}
public class ForLoop {
}
public static void printVector1(Vector v) {
for (Iterator it = v.iterator();it.hasNext();){
Object o = it.next();
System.out.println(o);
}
}
public static void main(String[]
p
g
args)
g
{
Vector v = new Vector(10);
for (int i = 0; i < 10; i++)
v.add (i, i*i);
printVector1(v);
printVector2(v);
}
Quelle: [Krüger]
0
0
1
1
4
4
9
9
16
16
25
25
36
36
49
49
64
64
81
81
Erweiterte for‐Schleife – Arrays
34
public static void printArray1(int[] args) {
for (int i = 0; i < args.length; ++i) System.out.println(args[i]);
}
public static void printArray2(int[] args) {
for (int a : args) System.out.println(a);
}
Wozu die erweiterte for‐Scheife
Wozu die erweiterte for
Scheife nicht
nicht genommen werden kann: genommen werden kann:

Das Durchlaufen der Collection von hinten nach vorn.

Das simultane Durchlaufen mehrerer Collections.

Das Löschen oder Ändern einzelner Elemente während des Durchlaufs.
Collections des Typ Set
35
Collection
I
I
Set
I
K
Iterator
SortedSet
I = Interface
K = Klassen
Abstract
Collection
K
AbstractSet
K
HashSet
TreeSet
K
JobState
Reasons
LinkedHash
Set
SortedSet ‐ Konstruktoren
36

Ein parameterloser Konstruktor erzeugt eine leere Menge, deren (zukünftige) Elemente bezüglich ihrer natürlichen Ordnung sortiert werden
Elemente bezüglich ihrer natürlichen Ordnung sortiert werden. 
Ein Konstruktor mit einem Argument des Typs Comparator erzeugt eine leere Menge, deren (zukünftige) Elemente bezüglich der durch den Comparator vorgegebenen Ordnung sortiert werden
vorgegebenen Ordnung sortiert werden. 
Ein Konstruktor mit einem Argument vom Typ Collection erzeugt eine Menge, die alle eindeutigen Elemente der als Argument übergebenen Collection in ihrer natürlichen Ordnung enthält. l h
d
h l

Ein Konstruktor mit einem Argument des Typs SortedSet erzeugt eine Menge mit denselben Elementen und derselben Sortierung wie die als Argument übergebene Menge. SortedSet ‐ Beispiel
37
import java.util.*;
//Konstruieren des Sets
TreeSet s = new TreeSet(new ReverseStringComparator());
public class MyTSortedSet {
public static void main(String[] args) {
//Konstruieren des Sets
TreeSet s = new TreeSet();
s.add("Kiwi");
s.add("Kirsche");
s.add("Ananas");
s.add("Zitrone");
s.add("Grapefruit");
s.add("Banane");
//Sortierte Ausgabe
Iterator it = s.iterator();
while (it.hasNext())
System.out.println((String)it.next());
}
}
Ananas
s.add("Kiwi");
s.add("Kirsche");
s.add("Ananas");
s.add("Zitrone");
s.add("Grapefruit");
s.add("Banane");
//Sortierte Ausgabe
for (Object o: s) System.out.println(o);
. . . . .
class ReverseStringComparator implements Comparator {
public int compare(Object o1, Object o2) {
return ((String)o2).compareTo((String)o1);
}
}
Zitrone
Banane
Kiwi
Grapefruit
Kirsche
Ki
Kirsche
h
G
Grapefruit
f it
Kiwi
Zitrone
Quelle: [Krüger]
Banane
Ananas
Die Klasse Collections
38


Die Klasse Collections enthält eine große Anzahl
Algorithmen (i.d.F.
(i d F statischer Methoden) zur Manipulation
Verarbeitung von Collections.
Methoden zum Durchsuchen, Sortieren, Kopieren
Synchronisieren von Collections sowie solche zur Extraktion
Elementen mit bestimmten Eigenschaften.




von
und
und
von
static void sort (List list)
static void sort (List list, Comparator c)
Fehlt der Comparator, wird die Liste in ihrer natürlichen Ordnung
sortiert.
i
Dazu müssen
ü
alle
ll Elemente
l
d Comparable‐Interface
das
C
bl I
f
implementieren und ohne Typfehler paarweise miteinander
vergleichbar sein.
Gemäß JDK‐Dokumentation verwendet diese Methode ein
modifiziertes Mergesort, das auch im Worst‐Case eine Laufzeit von
O(n*log(n))
O(n
log(n)) hat (auch bei der Klasse LinkedList) und damit auch für
große Listen geeignet sein sollte.
Collections: Problem Typsicherheit 1/2
39





Großes Problem mit Collections (bis Java 5): sie sind prinzipiell offen für
jjeden Typ.
yp
Man speichert Objekte vom allgemeinsten Typ Object.
Beim Lesen der Collection werden diese allgemeinen Objekte auch wieder
zurück geliefert.
geliefert
Wenn man in einer Collection Apfel‐Objekte speichert, will man dort
keine Birnen‐Objekte speichern – doch mit einen allgemeinen Typ
Object kann
a das nicht
c verhindert
e
de werden.
e de
Beispiel:
Apfel jona = new Apfel();
ArrayList apfelSpeicher = new ArrayList();
apfelSpeicher.add( jona );
fügt ein Element in die Liste ein,
ein es hätte aber auch apfelSpeicher.add(new
apfelSpeicher add(new
Birne()) oder apfelSpeicher.add("ätsch") sein können.

Der Fehler fällt beim Einfügen nicht auf, doch beim Wiederholen der
yp p
g folgt
g die (g
(gefürchtete))
Daten und anschließender Typanpassung
ClassCastException.
Collections: Problem Typsicherheit 2/2
40

Abhilfe seit Java 5 :

Die Collection‐API macht massiven Gebrauch der Generics.

Erst dadurch wird bessere Typsicherheit gewährleistet, denn nur ganz
spezielle Objekte kommen in die Datenstruktur.
Datenstruktur

Mit den Generics lässt sich bei der Konstruktion einer Collection‐
Datenstruktur angeben, welche Objekte in die Liste aufgenommen
werden dürfen.
Konkrete Container‐Klassen (kleine Auswahl)
41
Listen
ArrayList
LinkedList
Mengen
HashSet
TreeSet
Assoziativspeicher
HashMap
TreeMap
Schlange
LinkedList
Implementiert Listen-Funktionalität wie ein Vector. Sie erweitert
dabei die Klasse AbstractList. ArrayList implementiert die
Schnittstelle List.
LinkedList ist eine doppelt verkettete Liste, also eine Liste von
Einträgen mit einer Referenz auf den jeweiligen Nachfolger und
Vorgänger Das ist nützlich beim Einfügen und Löschen von
Vorgänger.
Elementen an beliebigen Stellen innerhalb der Liste. Diese
Klasse erweitert AbstractSequentialList.
Eine Implementierung der Schnittstelle Set durch ein schnelles
Hash Verfahren
Hash-Verfahren
Implementierung von Set durch einen Baum, der alle Elemente
sortiert hält
Implementiert einen assoziativen Speicher durch ein HashVerfahren. Sie erweitert die Klasse AbstractMap und ist damit
auch eine Map.
Exemplare dieser Klasse halten ihre Elemente in einem
Binärbaum sortiert. TreeMap erweitert AbstractMap und
implementiert SortedMap.
Die verkettete Liste implementiert auch Queue.
ArrayBlockingQueue Eine blockierende Warteschlage
Warteschlage.
PriorityQueue
Prioritätswarteschlange.
Herunterladen