Programmieren II. Hierarchie von Collections. Vorlesung 3. Handout S. 1. Dr. Klaus Höppner. Hochschule Darmstadt Sommersemester 2010

Ähnliche Dokumente
Collections und Iteratoren ListIterator Sets. Programmieren II. Dr. Klaus Höppner. Hochschule Darmstadt Sommersemester / 22

Programmieren II equals und hashcode

JAVA KURS COLLECTION

Einstieg in die Informatik mit Java

Programmieren I. Listen mit wahlfreiem Zugriff. Vorlesung 1. Handout S. 1. Martin Schultheiß. Hochschule Darmstadt Sommersemester 2011.

OCP Java SE 8. Collections

19 Collections Framework

12 Collections Framework. Interfaces Maps and Collections. Collection Interface. Überblick. Collection = Containterklasse, die andere Objekte enthält.

Lineare Datenstrukturen: Felder, Vektoren, Listen Modelle: math. Folge (a i ) i=1.. mit Basistyp T oder: [T]

Grundkonzepte java.util.list

19 Collections Framework

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 11/12 1. Kapitel 11. Listen. Listen

Objektorientierte Programmierung. Kapitel 21: Einführung in die Collection Klassen

Programmierkurs Java

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 16/17. Kapitel 13. Listen. Listen 1

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 15/16. Kapitel 12. Listen. Listen 1

Rechtsbelehrung. Java und OOP Das Buch Christian Silberbauer 144

Collections. Arthur Zaczek. Nov 2015

Programmieren in Java

ALP II Dynamische Datenmengen

Collections. Arthur Zaczek

Programmierkurs Java

Einführung in die Programmierung mit Java

Listen. Prof. Dr. Christian Böhm. in Zusammenarbeit mit Gefei Zhang. WS 07/08

Faulheit professionell: Fertige Datenbehälter. Das Java-Collections-Framework Typsicherheit Generische Klassen

Teil V. Generics und Kollektionen in Java

java.util. Sebastian Draack Department Informations- und Elektrotechnik Department Informations- und Elektrotechnik JAVA Collection-API

Mengen und Multimengen

IT I: Heute. abstrakte Methoden und Klassen. Interfaces. Interfaces List, Set und Collection IT I - VO 7 1

ADT: Java Collections und ArrayList

Nützliche Utility-Klassen des JDK

Problem: Was ist, wenn der Stapel voll ist? Idee: Erzeuge dynamisch ein grösseres Array und kopiere um. Dynamische Anpassung der Größe

Kapitel 4: Bäume i. 1. Einleitung. 2. Ein Datenmodell für Listen. 3. Doppelt-verkettete Listen. 4. Bäume. 5. Das Collections-Framework in Java

Programmiertechnik II

Programmiertechnik II

Einfache Liste: Ein Stapel (Stack) Ansatz. Schaubild. Vorlesung 1. Handout S. 2. Die einfachste Form einer Liste ist ein Stapel (stack).

Kapitel 5: Iterierbare Container

Kapitel 6: Java Collection Teil I

Programmieren in Java

Java Schulung. Objektorientierte Programmierung in Java Teil V: Die Java Collection Klassen. Prof. Dr. Nikolaus Wulff

Mengen und Multimengen

Vorlesung Programmieren

Java Einführung Collections

Java Collections Framework (JCF)

II.4.6 Collections - 1 -

Dynamische Datenstrukturen

Propädeutikum Programmierung in der Bioinformatik

Objektorientierte Implementierung

Die Java - Collections API

Inner Class. 1 public class OuterClass { 2 private int var; 3 public class InnerClass { 4 void methoda() {}; 5 } 6 public void methodb() {}; 7 }

Programmieren 2 16 Java Collections und Generizität

Aufgabenblatt 4. Aufgabe 3. Aufgabe 1. Aufgabe 2. Prof. Dr. Th. Letschert Algorithmen und Datenstrukturen

Datenstrukturen. Ziele

Kapitel 7: Java Collection Teil I

Java Generics & Collections

equals und hashcode SortedSet NavigableSet Assoziative Container Programmieren II Dr. Klaus Höppner Hochschule Darmstadt Sommersemester / 32

Programmieren I. Kapitel 13. Listen

Java I Vorlesung Collections

Übungsblatt Programmierung und Software-Entwicklung Generizität, Interfaces, Listen, Sortieralgorithmen & JUnit

Programmiertechnik II

Software Entwicklung 1

Programmieren in Java

TECHNISCHE UNIVERSITÄT MÜNCHEN FAKULTÄT FÜR INFORMATIK

Teil II) Objektorientierte Implementierung 10) Verfeinern von UML-Assoziationen mit dem Java-2 Collection Framework

Kapitel 12: Java Collection Teil II

Kapitel 12: Java Collection Teil II

4. Algorithmen und Datenstrukturen I Grundlagen der Programmierung 1 (Java)

Wo sind wir? Rudolf Berrendorf FH Bonn-Rhein-Sieg Programmiersprache Java 338

XIII: Verkettete Listen

3. Übungsbesprechung Programmkonstruktion

Grundlagen der Informatik 0

Java Generics & Collections

public interface Stack<E> { public void push(e e); public E pop();

II.4.4 Exceptions - 1 -

Polymorphie/Späte Bindung Abstrakte Klassen Interfaces. Polymorphie/Späte Bindung Abstrakte Klassen Interfaces

Programmieren in Java

17. Java Collections. Daten Organisieren. Generische Liste in Java: java.util.list. Typ Parameter (,,Parametrischer Polymorphisums )

Objektorientiertes Programmieren mit Java

Algorithmen und Datenstrukturen CS1017

Nachtrag: Vergleich der Implementierungen von Stack

Programmieren in Java

IT I: Heute. Klasse Object. equals, hashcode, tostring. HashSet IT I - VO 6 1

Abstrakte Datentypen und Java

Einführung in die Informatik

Teil VII. Hashverfahren

IT I: Heute. Klasse Object. equals, hashcode, tostring. HashSet IT I - VO 6 1

Beispielklausur A MPGI 3

Stacks, Queues & Bags. Datenstrukturen. Pushdown/Popup Stack. Ferd van Odenhoven. 19. September 2012

Allgemeine Informatik II

Programmierzertifikat Objekt-Orientierte Programmierung mit Java

Hashmap: Video Erklärung

Software Entwicklung 1

Algorithmen und Datenstrukturen in Java Jiri Spale, Algorithmen und Datenstrukturen in Java 1

Transkript:

Programmieren II Dr. Klaus Höppner Hochschule Darmstadt Sommersemester 2010 1 / 22 Collections und Iteratoren ListIterator Sets 2 / 22 Hierarchie von Collections Die sequenziellen Container (ArrayList & LinkedList) und Mengen implementieren das Interface Collection. Die assoziativen Container werden zwar auch häufig zu den Collections gezählt, sind aber tatsächlich unabhängig vom Interfaxe Collection, sondern implementieren in Wirklichkeit das Interfax Map. 3 / 22 Handout S. 1

Schaubild Das Interface Collection<E> 4 / 22 Ein großer Teil der Methoden aus dem Interface List der letzten Vorlesung stammen bereits aus Collection boolean add(e e) fügt ein Objekt e hinzu. void clear() löscht alle Werte aus der COllection. boolean contains(object o) prüft, ob es ein Element e gibt, für das der Ausdruck e.equals(o) wahr ist. boolean isempty() ist wahr, wenn die COllection leer ist. Iterator<E> iterator() gibt einen Iterator zurück. Dies ist ein bisher noch nicht behandeltes Sprachelement, das im Weiteren näher behandelt wird. Das Interface Collection<E> 5 / 22 boolean remove(object o) entfernt das erste Element, das zu o äquivalent ist. true, falls ein Element entfernt wurde. int size() Anzahl der Elemente. Object[] toarray() gibt alle Elemente der COllection als Array vom Typ Object[] zurück. T[] toarray(t[] a) füllt den übergebenen Array vom Typ T[] mit allen Elementen oder erzeugt einen neuen, wenn die Größe des Array nicht ausreicht. Rückgabewert ist der gefüllte Array. 6 / 22 Handout S. 2

Grundfunktionalität von Collections Beim Betrachen der Methoden werden die wesentlichen Gemeinsamkeiten aller Collections deutlich: Hinzufügen eines Objekts (add), Entfernen eines Objekts (remove), Prüfen, ob ein Objekt enthalten ist (contains) Indexbezogene Operationen kommen erst in List hinzu. Frage: Aber wie kann man z. B. alle Elemente einer Collection ausgeben? 7 / 22 Iteratoren Motivation Betrachten zunächst folgendes Beispiel: List<Double> l = new LinkedList<Double>(); // Füllen double summe = 0; for (int i=0; i<l.size(); i++) { summe += l.get(i).doublevalue(); Wie ist das Laufzeitverhalten der for-schleife? Die Zugriffszeit auf das Element i ist proportional zu i, die Laufzeit der Iteration daher proportional zu n 1 i=0 i. Das Ergebnis dieses Ausdruck verhält sich quadratisch, also ist die Iteration von der Ordnung n 2 (hierbei ist n die Länge der Liste). 8 / 22 Alternative Fassung Vergleichen wir das Verhalten der Summation über Indexzugriff mit folgender Fassung: List<Double> l = new LinkedList<Double>(); // Füllen double summe = 0; for (Double d : l) { summe += d.doublevalue(); Hier stellt man fest, dass die Laufzeit deutlich besser ist, denn in der for-schleife wird tatsächlich von Element zu Element gesprungen (während bei der Summation über Index bei jedem Schleifendurchlauf das passende Element jeweils neu abgezählt wird). Die Laufzeit ist somit insgesamt von der Ordnung n, wächst also linear mit der Länge der Liste. 9 / 22 Handout S. 3

Iteratoren Tatsächlich wird der Code for (Double d : l) {... intern wie folgt umgesetzt: for (Iterator<Double> iter=l.iterator(); iter.hasnext(); ) { Double d = iter.next(); //... Ein Iterator ist dabei ein Zeiger, der über alle Elemente einer Collection iterieren kann. Dieser besitzt die Methoden bool hasnext() Gibt es ein nachfolgendes Element? E next() holt den Wert des jeweils nächsten Elements. void remove() entfernt das zuvor mit next() geholte Element aus der darunterliegenden Collection (optional). In der bildlichen Vorstellung zeigt der Iterator immer zwischen zwei Elemente! 10 / 22 Anwendung Folgendes Programm simuliert die Ziehung der Lottozahlen (als Vorgeschmack auf Sets): Collection<Integer> c = new TreeSet<Integer>(); c.add(43); c.add(7); c.add(2); c.add(29); c.add(33); c.add(12); for (Iterator<Integer> iter=c.iterator(); iter.hasnext(); ) { Integer zahl = iter.next(); System.out.println(zahl); 11 / 22 Iterator ListIterator Der normale Iterator hat zwei Nachteile: Die Iteration ist nur in eine Richtung möglich. Über den Iterator können keine Elemente der darunter liegenden Collection ausgetausch werden. Für das Interface List gibt es einen erweiterten Iterator, den ListIterator. Dieser erlaubt Iterationen in beide Richtungen, Zugriff auf den Index eines Elementes und das Austauschen von Elementen. 12 / 22 Handout S. 4

Schaubild von ListIterator<E> Quelle: Ullenboom, Java ist eine Insel, 7. Aufl. Das Interface ListIterator<E> 13 / 22 Für ListIterator<E> kommen folgende Methoden hinzu: boolean hasprevious() Gibt es ein Vorgängerelement? int nextindex() Index des nächsten Elements. E previous() holt das Vorgängerelement. int previousindex() Index des vorigen Elements. void set(e e) ersetzt das beim letzten next() oder previous() geholte Element durch e. 14 / 22 Beispiel Im folgenden Beispiel werden in einer String-Liste alle Vorkommen von Klaus durch Otto ersetzt: List<String> l = new LinkedList<String>(); // Füllen ListIterator<String> iter; for (iter=l.listiterator(); iter.hasnext(); ) { String wert = iter.next(); if (wert=="klaus") { iter.set("otto"); System.out.println("Element an Index "+ iter.previousindex()+" ersetzt"); 15 / 22 Handout S. 5

Mengentypen: Set Ein Set (deutsch: Menge) in Java ist ein Interface, das von Collection erbt. Im Gegensatz zu List kommen hier aber keine neuen Methoden hinzu. Eine Implementation von Set unterstützt daher im Wesentlichen folgende Operationen: Hinzufügen neuer Element Entfernen von Elementen Prüfen darauf, ob ein Element vorhanden ist Hierbei gilt, dass ein einem Set niemals doppelte Einträge gibt, also für alle Paare e1 und e2 der Ausdruck e1.equals(e2) unwahr ist. 16 / 22 Sets und Sortierung Wie bei allen Collections ermöglicht die Methode iterator() eine Iteration über alle Elemente des Sets, was z. B. implizit benutzt wird durch: for (E e : myset) {... Normale Sets stellen dabei keinen Anspruch auf die Reihenfolge der Elemente bei der Iteration. Diese muss keiner Ordnung unterliegen (wie aufsteigend), noch muss diese reproduzierbar sein. Demgegenüber stellt das Interface SortedSet sicher, dass die Elemente immer anhand einer festen (vorgegebenen) Ordnung sortiert sind. 17 / 22 Die Implementierung HashSet Häufig wird für Mengen die Implementierung HashSet verwendet. Der grundsätzliche Aufbau soll durch eine einfache Analogie verdeutlicht werden. In der CD-Abteilung eines Kaufhauses werden die CDs nach folgendem System geordnet: Das Sortiment ist in Regale für einzelne Musikrichtungen unterteilt, im Regal einer Musikrichtung gibt es (je nach Bedeutung des/der Interpreten) eine Unterteilung nach einzelnen Interpreten bzw. einer Gruppe von Interpreten mit gleichem Anfangsbuchstaben, innerhalb der Unterteilung sind die CDs ungeordnet. 18 / 22 Handout S. 6

Beispiel Beispiel 1: U2, The Joshua Tree findet man unter Rock & Pop, dort unter U2, dann muss man alle CDs von U2 durchsuchen, bis man die richtige gefunden hat. Beispiel 2: Mambo Kurt, Back in Beige unter Rock & Pop, dort unter M diverse, und dort durchblättern, bis man die CD findet (sehr unwahrscheinlich!) Diese Ordnung entspricht einer Sortierung nach Hashes, hier auf zwei Ebenen: Kategorie und Interpret. Die Hashes engen die Suche ein, innerhalb der ungeordneten Menge von CDs mit gleichen Hashes hilft aber nur lineare Suche. Die Aufteilung nach Hashes ist dabei dynamisch. Veröffentlicht ein Interpret viele CDs, kriegt er irgendwann sein eigenes Fach! Technische Funktionsweise von HashSet<E> HashSet<E> unterteilt die Elemente (anhand einer Hash-Funktion) in n verschiedene Kategorien, mit den entsprechenden Indizes 0... n 1, und ordnet jedem dieser Indizes ein Bucket (Kübel) zu. Hierin liegen die Elemente mit gleicher Kategorie ungeordnet. Die Hash-Funktion greift dabei auf die Methode int hashcode() aus Object zurück. Besondere Eigenschaft hierbei ist, dass zunächst die Unterteilung der Hashwerte dabei sehr grob ist (wenig Buckets), und bei wachsender Zahl von Elementen die Unterteilung nach Hashwerten verfeinert wird (mehr Buckets), um die Zahl der Elemente in einem Bucket zu begrenzen. Dies nennt man Rehashing. 19 / 22 Zustandsparameter eines HashSet Der interne Zustand eines HashSet<E> wird durch zwei Parameter beschrieben: Kapazität (capacity) gibt die Zahl der Buckets an, d. h. je größer die Kapazität, desto feiner die Unterteilung in Hash-Kategorien. Füllfaktor (load factor) gibt das aktuelle Verhältnis der Gesamtzahl der Elemente zur Kapazität an. Dabei ist immer die Bedingung size load factor capacity 20 / 22 erfüllt, der Füllfaktor bestimmt also, wann ein Rehashing (meist auf doppelte Kapazität) durchgeführt wird. Üblicher Wert für den Füllfaktor ist 0.75. 21 / 22 Handout S. 7

Laufzeitverhalten Bezüglich des Laufzeitverhaltens verhalten sich Kapazität und Füllfaktor bei verschiedenen Operationen gegenläufig: Bei den Operationen add, remove und contains ist der Zugriff auf das passende Bucket von konstanter Laufzeit, das Durchsuchen der Elemente des Buckets (auch bei add zur Duplikatsprüfung) ist proportional zur mittleren Größe des Buckets (Size/Capacity), die durch den Load Factor nach oben begrenzt wird. Daher ist die Laufzeit im Prinzip konstant unter der Annahme einer homogenen Verteilung der Elemente auf die Hashes, wobei hier kleine Füllfaktoren vorteilhaft sind. Eine Iteration über alle Elemente braucht einen Iterationsschritt pro Bucket zzgl. einen je Element im Bucket, somit also Capacity (Size/Capacity + 1) = Capacity + Size 22 / 22 Handout S. 8