Softwaretechnik 1 Vorlesung 2.4. Java Collections Framework Java

Werbung
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 Klassenbibliothek
2
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/
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Java API Dokumentation
3
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
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.
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
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
Java Collections Framework
7
Übersicht über die wichtigsten Interfaces und Implementierungen
Vererbung (extends)
Implementierung (implements)
<<interface>>
Collection
<<interface>>
Set
<<interface>>
List
SortedSet
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Map
<<interface>>
SortedMap
BlockingQeue
ArrayList
TreeSet
<<interface>>
Queue
<<interface>>
<<interface>>
HashSet
<<interface>>
LinkedList
HashMap
PriorityQueue
ArrayBlockingQueue
TreeMap
Java Collections Framework
8
Übersicht über die wichtigsten Interfaces und Implementierungen
Vererbung (extends)
Implementierung (implements)
<<interface>>
Collection
<<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
Interface Collection
9
„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
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Interface Collection
10
verbindliche Operationen
• boolean contains(Object o)
• 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
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
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
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
Beispiel
13
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionBsp1 {
public static void main(String[] args) {
Collection c = new ArrayList();
for (int i = 0; i < 10; i++) {
c.add(i);
}
Iterator iterator = c.iterator();
while( iterator.hasNext() ) {
System.out.print( iterator.next() + " " );
}
}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Beispiel - Anpassbarkeit
14
import java.util.HashSet;
import java.util.Collection;
import java.util.Iterator;
public class CollectionBsp1 {
public static void main(String[] args) {
Collection c = new HashSet();
for (int i = 0; i < 10; i++) {
c.add(i);
}
Iterator iterator = c.iterator();
while( iterator.hasNext() ) {
System.out.print( iterator.next() + " " );
}
}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Listen
15
Vererbung (extends)
Implementierung (implements)
<<interface>>
Collection
<<interface>>
<<interface>>
List
Set
SortedSet
Seite
<<interface>>
Map
<<interface>>
SortedMap
BlockingQeue
ArrayList
TreeSet
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Queue
<<interface>>
<<interface>>
HashSet
<<interface>>
LinkedList
PriorityQueue
HashMap
ArrayBlockingQueue
TreeMap
Listen
16
Liste oder Sequenz von Objekten, geordnet
doppelte Elemente erlaubt
Einfügen von null erlaubt
zusätzliche verbindliche und optionale Operationen
bieten speziellen ListIterator mit erweiterter Funktionalität
Implementierungen
• ArrayList
•
•
•
•
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
• Listenimplementierung als doppelt verkettete Liste
• zusätzliche Operationen zum Einfügen/Entfernen/Zugriff auf Anfang
und Ende der Liste
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Listen
17
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.)
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
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
zusätzliche Operation zu herkömmlichen Iterator
verbindliche Operationen
• boolean hasPrevious()
• true, falls es noch vorhergehende Elemente existieren
• Object previous()
• liefert das vorhergehende Element
• int nextIndex()
• liefert den Index des nächsten mit next() gelieferten Elements
• int previousIndex()
• 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
20
dozent
Veranstaltung
titel
: String
sws : int
schein : boolean
zeit
: Calendar
*
1
Dozent
name : String
email : String
buero : int
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Listen - Beispiel
21
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);
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 - 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
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Listen Implementierungen
23
ArrayList und LinkedList sind konkrete Listenimplementierungen
Wann ist welche Liste sinnvoll?
Performancevergleich
• LinkedList
• 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
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Mengen
24
Vererbung (extends)
Implementierung (implements)
<<interface>>
Collection
<<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
Mengen
25
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
• keine garantierte Ordnung der Elemente bei Iteration
• basiert auf HashMap
• daher O(1) Performance für Basisoperationen (add, contains and remove)
• LinkedHashSet
• leitet von HashSet ab, garantiert aber die Reihenfolge der Elemente
(Einfügereihenfolge)
• 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
Interface SortedSet
26
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
• Object last()
• liefert das „größte“ Element der Menge
• SortedSet subSet(Object fromElement, Object
toElement)
• liefert die Teilmenge mit Elementen „größer gleich“ fromElement
und „echt kleiner“ als toElement
• SortedSet tailSet(Object fromElement)
• liefert die Teilmenge mit Elementen „größer gleich“ fromElement
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Mengen Beispiel
27
dozent
Veranstaltung
titel
: String
sws : int
schein : boolean
zeit
: Calendar
*
1
Dozent
name : String
email : String
buero : int
add(Teilnehmer t)
*
*
Teilnehmer
name : String
matrikel : int
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Mengen Beispiel
28
public class Veranstaltung {
Set teilnehmer;
public Veranstaltung(String titel, int sws,
boolean schein, Dozent dozent, Calendar zeit) {
...
this.teilnehmer = new HashSet();
}
public void addTeilnehmer(Teilnehmer t) {
teilnehmer.add(t);
}
public Set getTeilnehmer() {
return teilnehmer;
}
...
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Mengen Beispiel
29
Veranstaltung vl1 = new Veranstaltung(..);
Veranstaltung vl2 = new Veranstaltung(..);
Teilnehmer
Teilnehmer
Teilnehmer
Teilnehmer
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();
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
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
Schlangen
31
Vererbung (extends)
Implementierung (implements)
<<interface>>
Collection
<<interface>>
Set
<<interface>>
List
SortedSet
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
<<interface>>
Map
<<interface>>
SortedMap
BlockingQeue
ArrayList
TreeSet
Queue
<<interface>>
<<interface>>
HashSet
<<interface>>
LinkedList
PriorityQueue
HashMap
ArrayBlockingQueue
TreeMap
Schlangen
32
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
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Schlangen – Interface Queue
33
zusätzliche verbindliche Operationen
• Object element()
• liefert erstes Element der Schlange, entfernt es aber nicht, löst
NoSuchElementException aus, falls Schlange leer
• boolean offer(Object o)
• liefert true, falls o in die Schlange eingefügt werden konnte
• Object peek()
• liefert erstes Element der Schlange, entfernt es aber nicht, liefert
null, falls Schlange leer
• Object poll()
• liefert erstes Element der Schlange und entfernt es, liefert null,
falls Schlange leer
• 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
Schlangen – Interface BlockingQueue
34
zusätzliche optionale Operationen
• boolean add(Object o)
• fügt o sofort ein, löst IllegalStateException aus, falls nicht möglich
• int drainTo(Collection c)
• entfernt alle Elemente der Qeue und fügt sie in c ein
• int drainTo(Collection c, int maxElements)
• entfernt maximal maxElements und fügt sie in c ein
• boolean offer(Object o, long timeout, TimeUnit unit)
• fügt o ein, wartet maximal timeout Zeiteineinheiten (unit), falls nicht
sofort möglich
• Object poll(long timeout, TimeUnit unit)
• entfernt das erste Element der Schlange, wartet timeout Zeiteinheiten
(unit), falls nicht sofort möglich
• void put(Object o)
• 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 take()
• entfernt das erste Element der Schlange, wartet, falls nicht sofort möglich
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Schlangen Beispiel
35
dozent
Veranstaltung
titel
: String
sws : int
schein : boolean
zeit
: Calendar
BlockingQueue :
prueflinge
add(Teilnehmer t)
pruefung()
*
1
Dozent
name : String
email : String
buero : int
1
*
Teilnehmer
name : String
matrikel : int
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
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());
Iterator it = teilnehmer.iterator();
while(it.hasNext()) {
Teilnehmer t = (Teilnehmer)it.next();
TeilnehmerThread p =
new TeilnehmerThread(t ,this);
p.run();
}
}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Schlangen Beispiel
37
public class DozentThread extends Thread {
protected Veranstaltung veranstaltung;
protected Dozent dozent;
public void run() {
BlockingQueue pruefling = veranstaltung.getPrueflinge();
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
38
public class TeilnehmerThread extends Thread {
private Teilnehmer teilnehmer;
private Veranstaltung veranstaltung;
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){
}
}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Schlangen Beispiel
39
Beispiel:
Pruefungen fuer die VL Software Systems von Meier
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.
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
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
Assoziative Speicher (Maps)
40
Vererbung (extends)
Implementierung (implements)
<<interface>>
Collection
<<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
Assoziative Speicher
41
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
• 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)
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
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
optionale Operationen
• void clear()
• entfernt alle Schlüssel-Wert-Paare
• Object put(Object key, Object value)
• legt neuen Eintrag mit Schlüssel key und Wert value an, ersetzt
ggfs. vorhandene Einträge
• void putAll(Map t)
• fügt alle Einträge aus t ein
• Object remove(Object key)
• entfernt den Eintrag mit Schlüssel key und liefert entsprechenden
Wert zurück
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Interface SortedMap
44
verbindliche Operationen
• Comparator comparator()
• liefert den Comparator, der mit dem Map assoziiert ist
• Object firstKey()
• liefert den „kleinsten“ Schlüssel
• SortedMap headMap(Object toKey)
• liefert ein Teilmapping mit Schlüsseleinträgen „echt kleiner“ als
toKey
• Object lastKey()
• 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
Telefonbuch
• zu gegebenem Dozenten (Schlüssel) wird Telefonnummer
(Wert) gesucht
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");
telefonBuch.put(schmidt,1234);
telefonBuch.put(meier,5678);
telefonBuch.put(mueller,2345);
telefonBuch.put(schulz,6789);
System.out.println(telefonBuch.containsKey(schmidt)); // true
System.out.println(telefonBuch.get(schmidt));
// 1234
}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Map Beispiel
46
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");
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(schmidt2)); // false
System.out.println(telefonBuch.get(schmidt2));
// null
}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Map Beispiel
47
Lösung: Überschreiben von hashCode() und equals()
public class Dozent {
...
String nachName;
...
//@Override
public int hashCode() {
return nachName.hashCode();
}
//@Override
public boolean equals(Object obj) {
if (obj instanceof Dozent) {
return ((Dozent)obj).getNachName().equals(nachName);
}
return false;
}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
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
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);
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
Sortierung
• Datenstruktur selbst hält Element sortiert
• SortedSet oder SortedMap sortieren die Elemente bzw.
Schlüssel gemäß ihrer „natürlichen Ordnung“ bzw. aufgrund eine
explizit angegebenen „Vergleichers“
• 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
Interface Comparable
50
einzige Methode
• int compareTo(Object o)
• 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
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Map Beispiel
51
public class Dozent implements Comparable {
...
String nachName;
...
public int compareTo(Object o) {
Dozent d = (Dozent)o;
return this.nachName.compareTo(d.nachName);
}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Map Beispiel
52
public class CollectionBsp4 {
public void doIt() {
SortedMap telefonBuch = new TreeMap();
Dozent
Dozent
Dozent
Dozent
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);
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
einzige Methode
• int compare(Object o1, Object o2)
• Ergebnis < 0, falls o1 < o2
• Ergebnis = 0, falls o1 = o2
• Ergebnis > 0, falls o1 > o2
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Map Beispiel
54
public class CollectionBsp4 {
public void doIt() {
SortedMap telefonBuch = new TreeMap(new DozentComparator());
...
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
Algorithmen
55
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
• ...
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Klassen Collections
56
Sammlung von statischen Methoden auf Collections
Auswahl
• static void sort(List list, Comparator c)
• 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
Beispielanwendung: SelectionSort
57
einfaches Sortierverfahren mit O(n2) Performance
Prinzip:
• Iteration über alle n Elemente der Liste
• für jedes Elemente i:
• 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
12 11
12 11
^
12 38
^
| 29 38
^^
...
Beispielanwendung: SelectionSort
58
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();
//Teilliste erzeugen
List subList = l.subList(currentIndex,l.size());
//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
Seite
Eigene Collection Implementierung
59
Vererbung (extends)
Implementierung (implements)
<<interface>>
Collection
<<interface>>
<<interface>>
<<interface>>
List
Set
Queue
SortedSet
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
<<interface>>
SortedMap
BlockingQeue
ArrayList
TreeSet
Map
<<interface>>
<<interface>>
HashSet
<<interface>>
PriorityQueue
LinkedList
HashMap
ArrayBlockingQueue
TreeMap
Eigene Collection Implementierung
60
Object
Vererbung (extends)
AbstractCollection
AbstractSet
AbstractList
AbstractSequentialList
HashSet
TreeSet
AbstractQueue
PriorityQueue
ArrayList
LinkedList
AbstractMap
TreeMap
HashMap
ArrayBlockingQueue
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Eigene Collection Implementierung
61
abstrakte Klassen als „skeletal implementation“ der entsprechenden
Interfaces
minimieren den Aufwand, eigene Collections zu implementieren
modifizierende Operationen lösen
UnsupportedOperationException aus
API Dokumentation erläutert, welche Methoden für eine eigene
Implementierung zu überschreiben sind
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Eigene Collection - Stack
62
LIFO – Speicher
spezielle Operationen als Stack Interface:
public interface Stack {
public boolean empty();
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
Implementierung als Collection:
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() {
return internList.removeFirst();
}
return internList.getFirst();
}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Stack Beispiel
64
public interface Operation {
public void eval(Stack s);
}
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);
}
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Stack Beispiel
65
public class PostFixEval {
public static Operation PLUS = new Plus();
public static Operation MAL = new Mal();
public static Operation GETEILT = new Geteilt();
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();
}
public static void main(String[] args) {
PostFixEval e = new PostFixEval();
// 1+((3*4)/2) = 7
Object[] expression = {1,3,4,MAL,2,GETEILT,PLUS};
System.out.println(e.evaluate(expression));
}}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Stack Beispiel
66
1
3
4
pu
sh
(3
)
pu
sh
(1
)
Eingabe:
1
*
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);
}
}
…
+
pu
sh
(4
)
Seite
3
4
1
3
(3*4)
2
1
(3*4)
1
((3*4)/2
)
1
)
ev
al
(.
.
ev
al
(.
.
pu
sh
(2
)
ev
al
(.
.
)
)
1
1+((3*4)/2)
= 7
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Neuerungen in J2SE 5.0
67
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
Veranstaltung
titel
: String
sws : int
schein : boolean
zeit
: Calendar
add(Teilnehmer t)
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)
List<Veranstaltung> veranstaltungen = new ArrayList<Veranstaltung>();
veranstaltungen.add( new Veranstaltung(“SE1“) );
// compile Fehler : veranstaltungen.add( new Object() );
Iterator<Veranstaltung> listIt = veranstaltungen.listIterator();
while( listIt.hasNext() ) {
Veranstaltung temp = listIt.next();
temp.getTitel();
...
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
Neuerungen in J2SE 5.0
69
Interface Iterable
• einzige Methode im Interface
• Iterator<T> iterator()
• Interface wird von allen Collectionklassen implementiert
Erweitertes „for“ möglich
List<Veranstaltung> veranstaltungen = new ArrayList<Veranstaltung>();
veranstaltungen.add( new Veranstaltung(“SE1“) );
for (Veranstaltung v : veranstaltungen) {
v.getTitel();
...
}
Prof. Dr. B. Rumpe
Software Systems
Engineering
TU Braunschweig
Seite
„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
• leitetet von Vector ab
• bietet Operationen wie im vorigen Beispiel an
• Enumeration
• 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