Softwaretechnik 1 Vorlesung 2.4. Java Collections Framework Java

Werbung
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Java: Objektorientierte Sprache mit bekannten Konzepten
(Klassen, Interfaces, Packages, Sichtbarkeiten, Vererbung, ...)
zusätzlich: umfangreiche Klassenbibliothek aus der
Standardfunktionalität importiert werden kann
Java 2 Standard Edition 5.0 Klassenbibliothek:
• 3279 Klassen und Interfaces in 166 Packages
Ziel: Wiederverwendung
• schnellere Entwicklung
• weniger Fehler
• performantere Implementierung
Problem:
• Kennen der vorhandenen Funktionalität
• Entscheidung zwischen Alternativen
wichtiges Hilfsmittel: Java API Dokumentation
API = Application Programming Interface
http://java.sun.com/j2se/1.5.0/docs/api/
Softwaretechnik 1
Vorlesung
2.4. Java Collections Framework
Prof. Dr. Bernhard Rumpe
Software Systems Engineering
Technische Universität Braunschweig
http://www.sse.cs.tu-bs.de/
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Java API Dokumentation
3
Java Klassenbibliothek
2
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Java Klassenbibliothek - Beispiele
4
java.lang
• einfache Datentypen: Integer, Boolean, Double, ...
• Zugriff auf Umgebungsvariablen, Standard-Streams
• nebenläufige Programmierung, Threads
java.io
• Ein- / Ausgabe: Kapselung in Streams, Zugriff mittels Reader
und Writer
java.net
• Netzwerkprogrammierung: URLs, Sockets, Protokolle, ...
java.awt, javax.swing
• GUI-Programmierung: Fenster, Dialoge, Buttons, ...
java.util
• Hilfsklassen für Kalender- und Datumsfunktionalität,
Zufallszahlen, ...
• Java Collections Framework
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Java Collections Framework
5
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Collection
• Objekt, das eine Gruppe von Objekten repräsentiert
•
•
•
•
zur Strukturierung der Daten
entscheiden häufig über Effizienz der Operationen, Anwendung
vgl. Datenstrukturen aus AuD I,II und Prog I,II
bekannte Datenstrukturen ?
• Operationen zur Abfrage, Manipulation
• contains(..), size(), add(..), ...
Framework
• Definition (nach Pomberger/Blaschek): Ein "framework"
(Rahmenwerk, Anwendungsgerüst) ist eine Menge von
zusammengehörigen Klassen, die einen abstrakten Entwurf für
eine Problemfamilie darstellen.
Java Collections Framework
6
Vorteile
• reduzierter Programmieraufwand
• Anpassbarkeit und Optimierbarkeit
• erhöhte Performance
• weniger Fehler
• Interoperabilität von unabhängigen APIs
• erhöhte Wiederverwendbarkeit
• erhöhte Verständlichkeit
„Nachteil“
• erhöhter Einarbeitunsaufwand durch „erstes Lernen“
Umfang: ca. 45 Klassen und Interfaces im Package java.util
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Java Collections Framework
7
Seite
Übersicht über die wichtigsten Interfaces und Implementierungen
Collection
<<interface>>
List
Set
SortedSet
HashSet
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Queue
LinkedList
PriorityQueue
Collection
<<interface>>
<<interface>>
Map
List
Set
<<interface>>
HashSet
TreeMap
9
Queue
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Map
<<interface>>
SortedMap
BlockingQeue
ArrayList
TreeSet
<<interface>>
<<interface>>
SortedSet
HashMap
Interface Collection
<<interface>>
<<interface>>
SortedMap
ArrayBlockingQueue
Vererbung (extends)
Implementierung (implements)
<<interface>>
<<interface>>
BlockingQeue
ArrayList
TreeSet
<<interface>>
<<interface>>
<<interface>>
Übersicht über die wichtigsten Interfaces und Implementierungen
Vererbung (extends)
Implementierung (implements)
<<interface>>
<<interface>>
Java Collections Framework
8
PriorityQueue
LinkedList
HashMap
ArrayBlockingQueue
TreeMap
Interface Collection
10
verbindliche Operationen
• boolean contains(Object o)
„kleinster gemeinsamer Nenner“ der Collection Implementierungen
schreibt Operationen für den Zugriff und die Manipulation der
unterliegenden Daten vor
Besonderheiten:
• optionale Operationen sind in der API Dokumentation als
optional markiert und müssen nicht implementiert werden
• lösen zur Laufzeit UnsupportedOperationException aus
• aber: alle konkreten Implementierungen in java.util
implementieren alle optionalen Methoden
• Map ist Teil des Collections Framework, leitet aber nicht von
Collection ab
• liefert true, wenn die Collection o enthält
• boolean containsAll(Collection c)
• liefert true, wenn die Collection alle Elemente von c enthält
• boolean isEmpty()
• liefert true, wenn die Collection keine Elemente enthält
• Iterator iterator()
• liefert einen Iterator über alle Elemente
• int size()
• liefert die Anzahl der Elemente
• Object[] toArray()
• liefert ein Array, das die Elemente enthält
• Object[] toArray(Object[] a)
• wie oben, der Laufzeittyp des Array ist der von a
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Interface Collection
11
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
optionale Operationen
• boolean add(Object o)
• fügt o zur Collection hinzu
• boolean addAll(Collection c)
• fügt alle Elemente von c zur Collection hinzu
• void clear()
• leert die Collection
• boolean remove(Object o)
• entfernt o aus der Collection
• boolean removeAll(Collection c)
• entfernt alle Elemente von c aus der Collection
• boolean retainAll(Collection c)
• entfernt alle Elemente der Collection, die nicht in c sind
Iteratoren
12
jede Collection besitzt die Methode
• Iterator iterator()
Iteration über die Elemente der Collection
Interface Iterator
• verbindliche Operationen
• boolean hasNext()
• true, falls Collection weitere Elemente enthält
• Object next()
• liefert das nächste Element der Collection
• optionale Operationen
• void remove()
• löscht das letzte mit next() zurückgelieferte Element aus der
Collection
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Beispiel
13
Seite
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.HashSet;
import java.util.Collection;
import java.util.Iterator;
public class CollectionBsp1 {
public static void main(String[] args) {
public class CollectionBsp1 {
public static void main(String[] args) {
Collection c = new ArrayList();
Collection c = new HashSet();
for (int i = 0; i < 10; i++) {
c.add(i);
}
for (int i = 0; i < 10; i++) {
c.add(i);
}
Iterator iterator = c.iterator();
Iterator iterator = c.iterator();
while( iterator.hasNext() ) {
System.out.print( iterator.next() + " " );
}
while( iterator.hasNext() ) {
System.out.print( iterator.next() + " " );
}
}
}
}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Listen
15
Seite
Collection
<<interface>>
<<interface>>
List
Set
SortedSet
TreeSet
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Queue
LinkedList
PriorityQueue
zusätzliche verbindliche und optionale Operationen
bieten speziellen ListIterator mit erweiterter Funktionalität
Implementierungen
• ArrayList
Map
•
•
•
•
<<interface>>
SortedMap
BlockingQeue
ArrayList
Liste oder Sequenz von Objekten, geordnet
doppelte Elemente erlaubt
Einfügen von null erlaubt
<<interface>>
<<interface>>
<<interface>>
HashSet
<<interface>>
• Listenimplementierung als doppelt verkettete Liste
• zusätzliche Operationen zum Einfügen/Entfernen/Zugriff auf Anfang
und Ende der Liste
TreeMap
Listen
17
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
zusätzliche verbindliche Operationen
• Object get(int i)
• liefert das i-te Element der Liste
• int indexOf(Object o)
• liefert die Position des ersten Auftretens von o in der Liste
• int lastIndexOf(Object o)
• liefert die Position des letzten Auftretens von o in der Liste
• ListIterator listIterator()
• liefert den erweiterten Iterator für Listen
• ListIterator listIterator(int index)
• liefert den Iterator ab dem angegeben Index
• List subList(int fromIndex, int toIndex)
• liefert eine Teilliste von Position fromIndex (inkl.) bis Position
toIndex (exkl.)
Listenimplementierung auf Array Basis
benötigte Arraygröße wird dynamisch angepaßt
anfängliche Größe des Arrays kann angegeben werden
optimale Arraygröße kann erzwungen werden
• LinkedList
HashMap
ArrayBlockingQueue
Listen
16
Vererbung (extends)
Implementierung (implements)
<<interface>>
Seite
Beispiel - Anpassbarkeit
14
Listen
18
zusätzliche optionale Operationen
• void add(int index, Object element)
• fügt element an Position index ein
• boolean addAll(int index, Collection c)
• fügt alle Elemente von c in die Liste ein beginnend ab index
• Object remove(int i)
• entfernt das i-te Element der Liste
• Object set(int i, Object element)
• ersetzt das i-te Element der Liste durch element
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Listen und ListIterator
19
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Listen - Beispiel
20
zusätzliche Operation zu herkömmlichen Iterator
verbindliche Operationen
• boolean hasPrevious()
• true, falls es noch vorhergehende Elemente existieren
• Object previous()
dozent
Veranstaltung
• liefert das vorhergehende Element
titel
: String
sws : int
schein : boolean
zeit
: Calendar
• int nextIndex()
• liefert den Index des nächsten mit next() gelieferten Elements
• int previousIndex()
*
1
Dozent
name : String
email : String
buero : int
• liefert den Index des nächsten mit previous() gelieferten
Elements
optionale Operationen
• void add(Object o)
• fügt o in die Liste vor die aktuelle Iteratorposition ein
•
void set(Object o)
• ersetzt das letzte durch next() oder previous() gelieferte
Element durch o
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Listen - Beispiel
21
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
public List init() {
Dozent meier = new Dozent("Meier","[email protected]",123);
...
Calendar vl1Zeit = java.util.Calendar.getInstance();
vl1Zeit.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
vl1Zeit.set(Calendar.HOUR_OF_DAY, 9);
vl1Zeit.set(Calendar.MINUTE,45);
Veranstaltung vl1 = new Veranstaltung("Software Systems",3,
false,meier,vl1Zeit);
...
Veranstaltung vl2 = new Veranstaltung("Software Testen", 5,
true, mueller, vl2Zeit);
...
Veranstaltung vl3 = new Veranstaltung("Software Architektur", 4,
true, schulz, vl3Zeit);
...
Veranstaltung vl4 = new Veranstaltung("Psychologie", 4,
true, schmidt, vl4Zeit);
Listen - Beispiel
22
public void print() {
List veranstaltungen = init();
ListIterator listIt = veranstaltungen.listIterator();
while( listIt.hasNext() ) {
System.out.println(listIt.nextIndex() + ": " +
((Veranstaltung)listIt.next()).getTitel());
}
// 0: Software Systems
// 1: Software Testen
// 2: Software Architektur
// 3: Psychologie
while( listIt.hasPrevious() ) {
System.out.println(listIt.previousIndex() + ": " +
((Veranstaltung)listIt.previous()).getTitel());
}
// 3: Psychologie
// 2: Software Architektur
// 1: Software Testen
// 0: Software Systems
List veranstaltungen = new ArrayList(10);
veranstaltungen.add(vl1);
veranstaltungen.add(vl2);
veranstaltungen.add(vl3);
veranstaltungen.add(vl4);
return veranstaltungen;
}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Listen Implementierungen
23
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Mengen
24
ArrayList und LinkedList sind konkrete Listenimplementierungen
Wann ist welche Liste sinnvoll?
Performancevergleich
• LinkedList
Vererbung (extends)
Implementierung (implements)
<<interface>>
Collection
• schnelles Einfügen und Löschen in O(1) bzw. O(n)
• wahlfreier Zugriff in O(n)
• ArrayList
• wahlfreier Zugriff in O(1)
• Einfügen und Löschen u.U. teuer, reicht die Kapazität des Array nicht aus,
muss die gesamte Liste in ein neues Array umkopiert werden
evtl. eigene Performancemessung
Daumenregel:
• Bei häufigem Zugriff und seltenen Änderungsoperationen: ArrayList
• Bei häufigen Änderungen und seltenem wahlfreien Zugriff:
LinkedList
<<interface>>
Set
<<interface>>
List
SortedSet
TreeSet
Queue
<<interface>>
Map
<<interface>>
<<interface>>
HashSet
<<interface>>
<<interface>>
SortedMap
BlockingQeue
ArrayList
LinkedList
PriorityQueue
HashMap
ArrayBlockingQueue
TreeMap
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Mengen
25
Seite
keine Duplikate
keine Reihenfolge der Elemente
mittels SortedSet kann natürliche Ordnung der Elemente hergestellt werden
Mengenoperationen wie Vereinigung, Schnitt durch Standard Collection
Operationen addAll(), retainAll()
Implementierungen
• HashSet
verbindliche Operationen
• Comparator comparator()
• liefert den Comparator, der mit dem Set assoziiert ist
• Object first()
• lieferte das „kleinste“ Element der Menge
• SortedSet headSet(Object toElement)
• liefert die Teilmenge mit Elementen „echt kleiner“ als toElement
• keine garantierte Ordnung der Elemente bei Iteration
• basiert auf HashMap
• daher O(1) Performance für Basisoperationen (add, contains and remove)
• Object last()
• liefert das „größte“ Element der Menge
• LinkedHashSet
• SortedSet subSet(Object fromElement, Object
toElement)
• leitet von HashSet ab, garantiert aber die Reihenfolge der Elemente
(Einfügereihenfolge)
• liefert die Teilmenge mit Elementen „größer gleich“ fromElement
und „echt kleiner“ als toElement
• TreeSet
• aufsteigende natürliche Ordnung der Elemente
• basiert auf TreeMap
• O(log(n)) für Basisoperationen (add, remove and contains)
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
• SortedSet tailSet(Object fromElement)
• liefert die Teilmenge mit Elementen „größer gleich“ fromElement
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Mengen Beispiel
27
Seite
dozent
Veranstaltung
titel
: String
sws : int
schein : boolean
zeit
: Calendar
*
1
Interface SortedSet
26
Mengen Beispiel
28
public class Veranstaltung {
Dozent
Set teilnehmer;
name : String
email : String
buero : int
public Veranstaltung(String titel, int sws,
boolean schein, Dozent dozent, Calendar zeit) {
...
this.teilnehmer = new HashSet();
}
add(Teilnehmer t)
*
public void addTeilnehmer(Teilnehmer t) {
teilnehmer.add(t);
}
*
Teilnehmer
public Set getTeilnehmer() {
return teilnehmer;
}
...
name : String
matrikel : int
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Mengen Beispiel
29
Seite
Veranstaltung vl1 = new Veranstaltung(..);
Veranstaltung vl2 = new Veranstaltung(..);
Teilnehmer
Teilnehmer
Teilnehmer
Teilnehmer
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
pete = new Teilnehmer("Pete", 1);
jon = new Teilnehmer("Jon", 2);
marc = new Teilnehmer("Marc", 3);
sam = new Teilnehmer("Sam", 4);
vl1.addTeilnehmer(pete);
vl1.addTeilnehmer(jon);
vl1.addTeilnehmer(marc);
vl2.addTeilnehmer(pete);
vl2.addTeilnehmer(marc);
Set vl1Teilnehmer = vl1.getTeilnehmer();
Set vl2Teilnehmer = vl2.getTeilnehmer();
Mengen Beispiel
30
//vl1Teilnehmer = {Pete ,Jon ,Marc}
//vl2Teilnehmer = {Pete, Sam}
//Vereinigung bilden : Teilnehmer von vl1 oder vl2
Set union = vl1Teilnehmer;
// Achtung: keine Kopie!
union.addAll(vl2Teilnehmer);
Iterator iter = union.iterator();
while(iter.hasNext()) {
System.out.println(iter.next());
// union = {Pete, Jon,
Marc, Sam}
}
//Schnitt bilden : Teilnehmer von vl1 und vl2
Set intersection = vl1Teilnehmer;
intersection.retainAll(vl2Teilnehmer);
Iterator iter = intersection.iterator();
while(iter.hasNext()) {
System.out.println(iter.next()); // intersection = {Pete}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Schlangen
31
Seite
Collection
<<interface>>
<<interface>>
List
Set
<<interface>>
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Map
<<interface>>
SortedSet
<<interface>>
SortedMap
BlockingQeue
ArrayList
TreeSet
<<interface>>
Queue
<<interface>>
HashSet
Elemente geordnet
Zugriff normalerweise nach dem FIFO (first in, first out) Prinzip
Varianten:
• BlockingQueue (eigenes Interface): blockierender Zugriff bei
leerer oder voller Schlange
• PriorityQueue: Element mit höchster Priorität wird zuerst
zugegriffen
Implementierung
• viele Subklassen, speziell für nebenläufige Programmierung
(java.util.concurrent)
• PriorityBlockingQueue
• ArrayBlockingQueue
Vererbung (extends)
Implementierung (implements)
<<interface>>
HashMap
PriorityQueue
LinkedList
Schlangen
32
ArrayBlockingQueue
TreeMap
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Schlangen – Interface Queue
33
Seite
Schlangen – Interface BlockingQueue
34
zusätzliche verbindliche Operationen
• Object element()
zusätzliche optionale Operationen
• boolean add(Object o)
• fügt o sofort ein, löst IllegalStateException aus, falls nicht möglich
• liefert erstes Element der Schlange, entfernt es aber nicht, löst
NoSuchElementException aus, falls Schlange leer
• int drainTo(Collection c)
• entfernt alle Elemente der Qeue und fügt sie in c ein
• int drainTo(Collection c, int maxElements)
• boolean offer(Object o)
• entfernt maximal maxElements und fügt sie in c ein
• liefert true, falls o in die Schlange eingefügt werden konnte
• boolean offer(Object o, long timeout, TimeUnit unit)
• fügt o ein, wartet maximal timeout Zeiteineinheiten (unit), falls nicht
sofort möglich
• Object peek()
• liefert erstes Element der Schlange, entfernt es aber nicht, liefert
null, falls Schlange leer
• Object poll(long timeout, TimeUnit unit)
• entfernt das erste Element der Schlange, wartet timeout Zeiteinheiten
(unit), falls nicht sofort möglich
• Object poll()
• void put(Object o)
• liefert erstes Element der Schlange und entfernt es, liefert null,
falls Schlange leer
• fügt o ein, wartet, falls nicht sofort möglich
• int remainingCapacity()
• liefert die Anzahl der noch einfügbaren Elemente, bevor die Schlange
blockiert
• Object remove()
• liefert erstes Element der Schlange und entfernt es, löst
NoSuchElementException aus, falls Schlange leer
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
• Object take()
• entfernt das erste Element der Schlange, wartet, falls nicht sofort möglich
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Schlangen Beispiel
35
Seite
dozent
Veranstaltung
titel
: String
sws : int
schein : boolean
zeit
: Calendar
BlockingQueue :
prueflinge
add(Teilnehmer t)
pruefung()
*
1
Dozent
name : String
email : String
buero : int
Schlangen Beispiel
36
class Veranstaltung {
...
BlockingQueue prueflinge = new ArrayBlockingQueue(2);
public void pruefung() {
DozentThread doz = new DozentThread(dozent, this);
doz.start();
System.out.println("Pruefungen fuer die VL " + titel +
" von " + dozent.getNachName());
1
Iterator it = teilnehmer.iterator();
*
while(it.hasNext()) {
Teilnehmer t = (Teilnehmer)it.next();
TeilnehmerThread p =
new TeilnehmerThread(t ,this);
p.run();
}
Teilnehmer
name : String
matrikel : int
}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Schlangen Beispiel
37
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Schlangen Beispiel
38
public class DozentThread extends Thread {
protected Veranstaltung veranstaltung;
protected Dozent dozent;
public class TeilnehmerThread extends Thread {
private Teilnehmer teilnehmer;
private Veranstaltung veranstaltung;
public void run() {
BlockingQueue pruefling = veranstaltung.getPrueflinge();
public void run() {
long zoegern = (long)(new Random()).nextInt(3000);
try {
Thread.sleep(zoegern);
System.out.println(teilnehmer + " meldet sich an.");
BlockingQueue warteSchlange = veranstaltung.getPrueflinge();
if (warteSchlange.remainingCapacity() == 0) {
System.out.println(
teilnehmer.getName() + " muss warten.");
}
warteSchlange.put(teilnehmer);
System.out.println(teilnehmer.getName() +
" ist angemeldet.");
} catch (InterruptedException e){
int maxPruefungen = veranstaltung.getTeilnehmer().size();
int abgeschlPruefungen = 0;
while (abgeschlPruefungen < maxPruefungen) {
try {
Teilnehmer p =
(Teilnehmer)pruefling.poll(1000,TimeUnit.MILLISECONDS);
if (p == null) {
System.out.println(dozent + " forscht.");
} else {
System.out.println(dozent + " prueft " + p + ".");
abgeschlPruefungen++;
}
} catch (InterruptedException e) {}
}}
...
}
}
}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Schlangen Beispiel
39
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Assoziative Speicher (Maps)
40
Beispiel:
Pruefungen fuer die VL Software Systems von Meier
Vererbung (extends)
Implementierung (implements)
<<interface>>
Meier forscht.
Jon ist angemeldet.
Pete ist angemeldet.
Marc muss warten.
Meier prueft Jon.
Marc ist angemeldet.
Sam muss warten.
Meier prueft Pete.
Sam ist angemeldet.
Meier prueft Marc.
Meier prueft Sam.
Collection
Schlange leer, Meier kann forschen
Schlange voll, Marc muss warten
Wieder Kapazitäten vorhanden
Jetzt kann sich Marc anmelden
Schlange voll, Sam muss warten
Wieder Kapazitäten vorhanden
Jetzt kann sich Sam anmelden
<<interface>>
<<interface>>
List
Set
Seite
Assoziative Speicher
41
HashSet
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
• keine garantierte Ordnung der Schlüssel bei Iteration
• O(1) Performance für Basisoperationen (containsKey, get, put,
remove)
• LinkedHashMap
• leitet von HashMap ab, garantiert aber die Reihenfolge der
Schlüssel (Einfügereihenfolge)
• TreeMap
• aufsteigende natürliche Ordnung der Elemente
• O(log(n)) für Basisoperationen (containsKey, get, put, remove)
<<interface>>
Map
<<interface>>
SortedSet
Seite
speichert Key,Value-Paare
keine doppelten Schlüssel erlaubt
implementiert nicht Collection, weil z.B. add(Object) keinen Sinn
ergibt
bietet Collection „Sichten“, z.B. durch Collection der Key oder
Values
Implementierungen
• HashMap
Queue
<<interface>>
<<interface>>
SortedMap
BlockingQeue
ArrayList
TreeSet
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
<<interface>>
PriorityQueue
LinkedList
HashMap
ArrayBlockingQueue
TreeMap
Interface Map
42
verbindliche Operationen
• boolean containsKey(Object key)
• liefert true, falls Eintrag mit Schlüssel key enthalten ist
• boolean containsValue(Object value)
• liefert true, falls zu value ein oder mehr Einträge vorhanden sind
• Set entrySet()
• liefert eine Set-Sicht auf die Einträge, Elemente sind vom Typ Map.Entry
• Object get(Object key)
• liefert den Wert zum Schlüssel key, liefert null falls Mapping nicht
existiert oder null der Wert ist
• boolean isEmpty()
• liefert true, falls keine Schlüssel-Wert-Paare gespeichert sind
• Set keySet()
• liefert eine Set-Sicht auf die Schlüssel
• int size()
• liefert die Anzahl der Schlüssel-Wert-Paare
• Collection values()
• liefert eine Collection-Sicht auf die Werte
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Interface Map
43
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Interface SortedMap
44
optionale Operationen
• void clear()
verbindliche Operationen
• Comparator comparator()
• liefert den Comparator, der mit dem Map assoziiert ist
• entfernt alle Schlüssel-Wert-Paare
• Object put(Object key, Object value)
• Object firstKey()
• legt neuen Eintrag mit Schlüssel key und Wert value an, ersetzt
ggfs. vorhandene Einträge
• liefert den „kleinsten“ Schlüssel
• SortedMap headMap(Object toKey)
• void putAll(Map t)
• liefert ein Teilmapping mit Schlüsseleinträgen „echt kleiner“ als
toKey
• fügt alle Einträge aus t ein
• Object remove(Object key)
• Object lastKey()
• entfernt den Eintrag mit Schlüssel key und liefert entsprechenden
Wert zurück
• liefert den „größten“ Schlüssel
• SortedMap subMap(Object fromKey, Object toKey)
• liefert ein Teilmapping mit Schlüsseleinträgen von fromKey (inkl.)
bis toKey (exkl.)
• SortedMap tailMap(Object fromKey)
• liefert ein Teilmapping mit Schlüsseleinträgen „größer gleich“
fromKey
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Map Beispiel
45
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Telefonbuch
• zu gegebenem Dozenten (Schlüssel) wird Telefonnummer
(Wert) gesucht
public class CollectionBsp4 {
public void doIt() {
Map telefonBuch = new HashMap();
Dozent
Dozent
Dozent
Dozent
Problem, falls nicht mit identischem Schlüssel nach dem Wert
gefragt wird
public class CollectionBsp4 {
public void doIt(){
Map telefonBuch = new HashMap();
Dozent
Dozent
Dozent
Dozent
schmidt = new Dozent("Schmidt");
meier = new Dozent("Meier");
mueller = new Dozent("Müller");
schulz = new Dozent("Schulz");
schmidt = new Dozent("Schmidt");
meier = new Dozent("Meier");
mueller = new Dozent("Müller");
schulz = new Dozent("Schulz");
telefonBuch.put(schmidt,1234);
telefonBuch.put(meier,5678);
telefonBuch.put(mueller,2345);
telefonBuch.put(schulz,6789);
telefonBuch.put(schmidt,1234);
telefonBuch.put(meier,5678);
telefonBuch.put(mueller,2345);
telefonBuch.put(schulz,6789);
Dozent schmidt2 = new Dozent("Schmidt");
System.out.println(telefonBuch.containsKey(schmidt)); // true
System.out.println(telefonBuch.get(schmidt));
// 1234
System.out.println(telefonBuch.containsKey(schmidt2)); // false
System.out.println(telefonBuch.get(schmidt2));
// null
}
}
}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Map Beispiel
46
Map Beispiel
47
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Lösung: Überschreiben von hashCode() und equals()
public class Dozent {
Map Beispiel
48
Aufgabe: Ausgabe des Telefonbuchs (z.B. für den Druck)
public class CollectionBsp4 {
public void doIt(){
Map telefonBuch = new HashMap();
Dozent
Dozent
Dozent
Dozent
...
String nachName;
...
//@Override
public int hashCode() {
return nachName.hashCode();
}
schmidt = new Dozent("Schmidt");
meier = new Dozent("Meier");
mueller = new Dozent("Müller");
schulz = new Dozent("Schulz");
telefonBuch.put(schmidt,1234);
telefonBuch.put(meier,5678);
telefonBuch.put(mueller,2345);
telefonBuch.put(schulz,6789);
//@Override
public boolean equals(Object obj) {
if (obj instanceof Dozent) {
return ((Dozent)obj).getNachName().equals(nachName);
}
return false;
}
Iterator iter = telefonBuch.keySet().iterator();
while(iter.hasNext()) {
Dozent d = (Dozent)iter.next();
System.out.println(d.getNachName() + " : "
telefonBuch.get(d));
}
}
}
}
//Schulz : 6789
//Müller : 2345
//Meier : 5678
//Schmidt : 1234
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Von Datenstrukturen zu Algorithmen...
49
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Interface Comparable
50
Sortierung
• Datenstruktur selbst hält Element sortiert
einzige Methode
• int compareTo(Object o)
• SortedSet oder SortedMap sortieren die Elemente bzw.
Schlüssel gemäß ihrer „natürlichen Ordnung“ bzw. aufgrund eine
explizit angegebenen „Vergleichers“
• Ergebnis < 0, falls das Objekt kleiner als Objekt o ist
• Ergebnis = 0, falls das Objekt gleich Objekt o ist
• Ergebnis > 0, falls das Objekt größer Objekt o ist
• Elemente explizit sortieren
• Methode sort() aus der Klasse Collections
• Elemente müssen paarweise vergleichbar sein
• Implementieren des Interface Comparable
• Implementieren einer Comparator-Klasse, die den Vergleich
vornimmt
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Map Beispiel
51
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
public class Dozent implements Comparable {
Map Beispiel
52
public class CollectionBsp4 {
public void doIt() {
SortedMap telefonBuch = new TreeMap();
Dozent
Dozent
Dozent
Dozent
...
String nachName;
...
schmidt = new Dozent("Schmidt");
meier = new Dozent("Meier");
mueller = new Dozent("Müller");
schulz = new Dozent("Schulz");
telefonBuch.put(schmidt,1234);
telefonBuch.put(meier,5678);
telefonBuch.put(mueller,2345);
telefonBuch.put(schulz,6789);
public int compareTo(Object o) {
Dozent d = (Dozent)o;
return this.nachName.compareTo(d.nachName);
}
}
Iterator iter = telefonBuch.keySet().iterator();
while(iter.hasNext()) {
Dozent d = (Dozent)iter.next();
System.out.println(d.getNachName() + " : "
telefonBuch.get(d));
}
//Meier : 5678
//Müller : 2345
//Schmidt : 1234
//Schulz : 6789
}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Interface Comparator
53
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
einzige Methode
• int compare(Object o1, Object o2)
Map Beispiel
54
public class CollectionBsp4 {
public void doIt() {
SortedMap telefonBuch = new TreeMap(new DozentComparator());
• Ergebnis < 0, falls o1 < o2
• Ergebnis = 0, falls o1 = o2
• Ergebnis > 0, falls o1 > o2
...
Iterator iter = telefonBuch.keySet().iterator();
while(iter.hasNext()) {
Dozent d = (Dozent)iter.next();
System.out.println(d.getNachName() + " : "
telefonBuch.get(d));
}
}
}
public class DozentComparator implements Comparator {
public int compare(Object o1, Object o2) {
Dozent d1 = (Dozent)o1;
Dozent d2 = (Dozent)o2;
return d2.getNachName().compareTo(d1.getNachName());
}
}
//
//
//
//
Schulz : 6789
Schmidt : 1234
Müller : 2345
Meier : 5678
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Algorithmen
55
Seite
Klassen Collections
56
Sammlung von statischen Methoden auf Collections
Auswahl
• static void sort(List list, Comparator c)
Beispiele
• sortieren
• kopieren
• suchen und ersetzen
• zählen, wie oft ein Element vorkommt
• größtes, kleinstes Element suchen
• rotieren
• Reihenfolge umkehren
• zufällig anordnen
• Elemente vertauschen
• ...
• sortiert list gemäßt Comparator c
• opt. mergesort, stabil, garantiert O(n log(n))
• static int frequency(Collection c, Object o)
• zählt Häufigkeit von o in c
• static void shuffle(List list, Random rnd)
• ordnet Elemente zufällig an
• static void swap(List list, int i, int j)
• vertauscht i-tes und j-tes Element
• static Collection
synchronizedCollection(Collection c)
• liefert eine Thread-sichere Collection für c
• entsprechende Methoden für List, Map, Set
• ...
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Beispielanwendung: SelectionSort
57
Seite
einfaches Sortierverfahren mit O(n2) Performance
Prinzip:
• Iteration über alle n Elemente der Liste
• für jedes Elemente i:
public static List sort(List l) {
ListIterator it = l.listIterator();
while (it.hasNext()) {
//aktuellen Index und aktuelles Objekt merken
int currentIndex = it.nextIndex();
Comparable currentObject = (Comparable)it.next();
• finde Minimum m in der Teilliste (i,..,n)
• vertausche m mit Element i
Bsp: Liste l = {38, 04, 29, 12, 11}
38 04 29
^ ^
04 | 38 29
^
04 11 | 29
^
04 11 12
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
//Teilliste erzeugen
List subList = l.subList(currentIndex,l.size());
12 11
12 11
^
12 38
^
| 29 38
^^
Beispielanwendung: SelectionSort
58
//Minimum finden und Index merken
Comparable minObj = (Comparable)Collections.min(subList);
int minIndex = l.indexOf(minObj);
//ggfs. Elemente vertauschen
if (minObj.compareTo(currentObject) < 0) {
Collections.swap(l,currentIndex, minIndex);
}
...
}
return l;
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Eigene Collection Implementierung
59
Seite
Vererbung (extends)
Implementierung (implements)
<<interface>>
Collection
Eigene Collection Implementierung
60
Object
Vererbung (extends)
AbstractCollection
<<interface>>
Set
<<interface>>
List
<<interface>>
Queue
<<interface>>
Map
AbstractSet
<<interface>>
<<interface>>
SortedSet
HashSet
TreeSet
LinkedList
PriorityQueue
AbstractQueue
AbstractMap
SortedMap
BlockingQeue
ArrayList
AbstractList
<<interface>>
AbstractSequentialList
HashMap
ArrayBlockingQueue
TreeMap
HashSet
TreeSet
PriorityQueue
ArrayList
LinkedList
TreeMap
HashMap
ArrayBlockingQueue
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Eigene Collection Implementierung
61
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Eigene Collection - Stack
62
abstrakte Klassen als „skeletal implementation“ der entsprechenden
Interfaces
minimieren den Aufwand, eigene Collections zu implementieren
modifizierende Operationen lösen
UnsupportedOperationException aus
LIFO – Speicher
spezielle Operationen als Stack Interface:
public interface Stack {
public boolean empty();
API Dokumentation erläutert, welche Methoden für eine eigene
Implementierung zu überschreiben sind
public void push (Object o);
public Object pop();
public Object peek();
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Eigene Collection - Stack
63
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Stack Beispiel
64
Implementierung als Collection:
public interface Operation {
public void eval(Stack s);
}
public class SimpleStack extends AbstractCollection implements Stack {
LinkedList internList;
public SimpleStack() {
internList = new LinkedList();
}
public void push(Object o) {
public Iterator iterator() {
return internList.iterator();
}
internList.addFirst(o);
}
public int size() {
return internList.size();
}
public Object pop() {
public boolean empty() {
return internList.size() == 0;
}
public Object peek() {
class Mal implements Operation {
public void eval(Stack s) {
int arg1 = (Integer)s.pop();
int arg2 = (Integer)s.pop();
s.push(arg2*arg1);
}
}
class Plus implements Operation {
public void eval(Stack s) {
int arg1 = (Integer)s.pop();
int arg2 = (Integer)s.pop();
s.push(arg2+arg1);
}
}
class Geteilt implements Operation {
public void eval(Stack s) {
int arg1 = (Integer)s.pop();
int arg2 = (Integer)s.pop();
s.push(arg2/arg1);
}
}
return internList.removeFirst();
}
return internList.getFirst();
}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Stack Beispiel
65
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Stack Beispiel
66
public class PostFixEval {
Eingabe:
1
3
4 *
2
…
Stack s = new SimpleStack();
for (int i = 0; i < expression.length; i++) {
if (expression[i] instanceof Integer ) {
s.push(expression[i]);
}
else {
((Operation)expression[i]).eval(s);
}
}
…
/ +
PostFixEval e = new PostFixEval();
// 1+((3*4)/2) = 7
Object[] expression = {1,3,4,MAL,2,GETEILT,PLUS};
System.out.println(e.evaluate(expression));
}}
pu
sh
(4
)
pu
sh
(3
)
3
4
1
3
(3*4)
2
1
(3*4)
1
((3*4)/2
)
1
)
ev
al
(.
.
ev
al
(.
.
)
)
1
pu
sh
(2
)
public static void main(String[] args) {
1
ev
al
(.
.
public int evaluate(Object[] expression) {
Stack s = new SimpleStack();
for (int i = 0; i < expression.length; i++) {
if (expression[i] instanceof Integer ) {
s.push(expression[i]);
} else {
((Operation)expression[i]).eval(s);
}
}
return (Integer)s.peek();
}
pu
sh
(1
)
public static Operation PLUS = new Plus();
public static Operation MAL = new Mal();
public static Operation GETEILT = new Geteilt();
1+((3*4)/2)
= 7
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Neuerungen in J2SE 5.0
67
Seite
Kritik an JDK1.2 Collections
• umständliche Verwendung der Iteratoren, kein „for each“
• keine Typ-Sicherheit, da Collections nur allgemein Object
aufnehmen
List veranstaltungen = new ArrayList();
veranstaltungen.add( new Veranstaltung(“SE1“) );
veranstaltungen.add( new Object() );
Iterator listIt = veranstaltungen.listIterator();
while( listIt.hasNext() ) {
Veranstaltung temp =
(Veranstaltung)listIt.next();
temp.getTitel();
...
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Neuerungen in J2SE 5.0
68
Generics (grob)
• Collections lassen sich für einen bestimmten Typ
parametrisieren
• Compiler meldet Fehler, wenn falscher Typ verwendet wird
• erhöht Typsicherheit und vermeidet Laufzeitfehler
(ClassCastException)
Veranstaltung
titel
: String
sws : int
schein : boolean
zeit
: Calendar
List<Veranstaltung> veranstaltungen = new ArrayList<Veranstaltung>();
veranstaltungen.add( new Veranstaltung(“SE1“) );
// compile Fehler : veranstaltungen.add( new Object() );
Iterator<Veranstaltung> listIt = veranstaltungen.listIterator();
add(Teilnehmer t)
Neuerungen in J2SE 5.0
69
while( listIt.hasNext() ) {
Veranstaltung temp = listIt.next();
temp.getTitel();
...
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Interface Iterable
• einzige Methode im Interface
• Iterator<T> iterator()
• Interface wird von allen Collectionklassen implementiert
Erweitertes „for“ möglich
„Alte Collections“
70
dargestelltes Collection Framework existiert seit JDK 1.2
vorher gab es aber auch schon Collection Klassen
• Vector
• entspricht ArrayList
• Thread-sicher (synchronized)
• implementiert jetzt auch Interface List
• Stack
List<Veranstaltung> veranstaltungen = new ArrayList<Veranstaltung>();
veranstaltungen.add( new Veranstaltung(“SE1“) );
• leitetet von Vector ab
• bietet Operationen wie im vorigen Beispiel an
• Enumeration
for (Veranstaltung v : veranstaltungen) {
v.getTitel();
...
}
• entspricht Iterator
• längere Methodennamen und irreführender Name
• Hashtable
• entspricht HashMap
• Thread-sicher
• implemetiert jetzt auch Interface Map
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Java Collections Framework
71
Quellen
•
•
•
•
•
http://java.sun.com/j2se/1.5.0/docs/api/
http://java.sun.com/docs/books/tutorial/collections/index.html
http://java.sun.com/j2se/1.5.0/docs/guide/collections/index.html
http://www.jeckle.de/vorlesung/java/script.html
http://www.javabuch.de/ (online Version von Guido Krügers
Handbuch der Java-Programmierung 4. Auflage)
• http://www.galileocomputing.de/openbook/javainsel4/ (online
Version von Christian Ullenbooms „Java ist auch eine Insel“ 4.
Auflage)
Herunterladen