Maximale Größe?! Problem: Was ist, wenn der Stapel voll ist? Idee: Erzeuge dynamisch ein grösseres Array und kopiere um Dynamische Anpassung der Größe Praktische Informatik I, HWS 2009, Kapitel 10 Seite 11 Dynamische Anpassung UltimativerStringStapel Enthält Merker für Aktuelle Größe Aktuelle Kapazität Blockgröße für den Anfang und jede Vergrößerung Wenn die Kapazität erschöpft ist: Erzeuge neues Array Kopiere alte Daten in neues Array Anpassung der Merker Praktische Informatik I, HWS 2009, Kapitel 10 Seite 12 Java-Stack: java.util.Stack Generischer Stack aus Java-Library Stack<E>() z.B. Stack<String> Dynamische Anpassung der Größe Methoden: Praktische Informatik I, HWS 2009, Kapitel 10 Seite 13 Java-Listen: ArrayList<E> Generische Klasse für Listen aus der JavaBibliothek Inhalt ist wie ein Array organisiert Klasse ArrayList im Paket java.util Methoden z.B. add() size() get() Beispiel für eine generische Klasse Klasse beschreibt eine Menge von Klassen über den Parameter E Praktische Informatik I, HWS 2009, Kapitel 10 Seite 14 Projekt Notizbuch Klasse Notizbuch soll eine beliebig lange Liste von Notizen speichern Notizen werden durch Indexnummern angesprochen und können vom Benutzer ausgelesen werden Gewünschte Schnittstelle: public class Notizbuch { /** Führe die Initialisierungen durch, die für * ein Notizbuch notwendig sind. */ public Notizbuch() { ... } /** Speichere eine neue Notiz in diesem Notizbuch. */ public void speichereNotiz(String notiz) { ... } /** Gib die Anzahl der Notizen in diesem Notizbuch. */ public int anzahlNotizen() { ... } /** Zeige eine Notiz mit der angegebenen Nummer */ public void zeigeNotiz(int notiznummer) { ... } /** Alle Notizen ausgeben */ public void notizenAusgeben() { ... } } Praktische Informatik I, HWS 2009, Kapitel 10 Seite 15 Implementierung mit ArrayList import java.util.ArrayList; ArrayList sichtbar machen Speicher für eine beliebig lange Liste von Notizen public class Notizbuch { private ArrayList<String> notizen; public Notizbuch() { notizen = new ArrayList<String>(); } public void speichereNotiz(String notiz) { notizen.add(notiz); } public int anzahlNotizen() { return notizen.size(); } ... } Praktische Informatik I, HWS 2009, Kapitel 10 ArrayList<String> ist eine Liste von Strings ArrayList<Integer> ist eine Liste von ints ArrayList<Konto> ist eine Liste von Kontos ... Speicher initialisieren im Konstruktor x.add(y) speichert Element y ans Ende der Liste x ab y muss vom bei der Deklaration der ArrayList angegebenen Typ sein x.size() liefert die Länge der Liste Seite 16 Experimente Inspiziere meinBuch Indexnummern entsprechen der Position im internen Array Zählung beginnt bei Index 0 Nächstes Element landet an Index 2 Praktische Informatik I, HWS 2009, Kapitel 10 Seite 17 Implementierung (Fortsetzung) public class Notizbuch { // Speicher für eine beliebige // Anzahl an Notizen. private ArrayList<String> notizen; ... public void zeigeNotiz(int notiznummer) { if ((notiznummer >= 0) && (notiznummer < anzahlNotizen()) { // Die Notiznummer ist gueltig System.out.println(notizen.get(notiznummer)); Gültigkeit des übergebenen Index prüfen x.get(i) gibt den in der Liste an Index i gespeicherten Wert zurück. Wert ist vom bei der Deklaration der ArrayList angegebenen Typ } } public void notizenAusgeben() { for (int i=0; i < anzahlNotizen(); i++) { System.out.println(zeigeNotiz(i)); } } } Praktische Informatik I, HWS 2009, Kapitel 10 Über alle gültigen Indizes gehen und die jeweilige Notiz ausgeben. Seite 18 Eine Sammlung durchlaufen Verwendung einer Indexvariablen in der for-Schleife ist komplex und fehleranfällig Abbruchbedingung i < x oder i ≤ x? Hochzählen i++ vergessen? Eleganter: Verwenden eines Iterators Ein Iterator ist ein Objekt, mit dem man eine ArrayList durchlaufen kann ArrayList hat Methode iterator(), die ein Iterator-Objekt liefert Ein Iterator hat zwei Methoden: import java.util.Iterator; ... public void notizenAusgeben() { Iterator<String> it = notizen.iterator(); boolean hasNext() liefert true genau dann, wenn es noch weitere Elemente gibt next() liefert das jeweils nächste Element Praktische Informatik I, HWS 2009, Kapitel 10 while (it.hasNext()) { System.out.println(it.next()); } } Seite 19 Index, Iterator, for each Index und Iterator für ArrayList etwa gleich gut Es gibt neben ArrayList noch weitere Klassen für Objektsammlungen HashSet, LinkedList, PriorityQueue, Vector ... Implementieren alle das Interface Collection Zur Verwendung siehe Java-Dokumentation Bei manchen kann man auf die Elemente nicht mit einem Index zugreifen Ein Interface ist eine Art abstrakte Klasse, mehr dazu später Hier muss man einen Iterator verwenden Bei Objektsammlungen kann man sogar noch einfachere Schleifen schreiben („for each“) Geht nur in Java, nicht in C notizen muss hier eine Collection von String sein Äquivalent zur Schleife mit Iterator von der vorherigen Folie Praktische Informatik I, HWS 2009, Kapitel 10 import java.util.Iterator; ... public void notizenAusgeben() { for (String notiz : notizen) { System.out.println(notiz); } } Seite 20 Anonyme Objekte Beim Füllen von Sammlungen muss man häufig zwei Dinge gleichzeitig machen: Beispiel: Objekte erzeugen und Objekte in die Sammlung einfügen. ArrayList<Konto> kontenListe = new ArrayList<Konto>; Konto billKonto = new Konto(“Bill”); kontenListe.add(billKonto); Kann das auch so schreiben: ArrayList<Konto> kontenListe = new ArrayList<Konto>; kontenListe.add(new Konto(“Bill”)); Äquivalent zum obigen Beispiel, wenn der Name billKonto nicht mehr gebraucht wird. Wir erzeugen damit ein Objekt ohne Bezeichnung: ein anonymes Objekt Praktische Informatik I, HWS 2009, Kapitel 10 Seite 21 Warteschlange (Queue) Stapel ist eine Datenstruktur, wo das zuletzt eingelegte Element zuerst wieder herauskommt Häufig benötigt man eine Datenstruktur, wo das zuerst eingelegte Element zuerst rauskommt Last In First Out (LIFO) First In First Out (FIFO) Schnittstelle der Datenstruktur Warteschlange: Queue() offer(e) poll() peek() leere Warteschlange erzeugen Element e ans Ende der Schlange einfügen Anfangselement der Schlange entnehmen Anfangselement anschauen Anwendungsbeispiele: Webserver mit eingehenden Anfragen Handelssystem mit eingehenden Kauf-/Verkaufsorders Praktische Informatik I, HWS 2009, Kapitel 10 Seite 22 Verwendung: Orderbuch Verwende eine OrderQueue mit Methoden offer(x) und poll() Praktische Informatik I, HWS 2009, Kapitel 10 Seite 23 Ein Ringpuffer: OrderQueue Array wird ringförmig gefüllt und entleert Zwei Indizes: hinten – zeigt auf erstes freies Element Hier wird eingefügt vorne – zeigt auf erstes belegtes Element Hier wird herausgenommen Praktische Informatik I, HWS 2009, Kapitel 10 Seite 24 Dynamische Größe Falls Queue voll ist, Speicher dynamisch erweitern Vorsicht beim Umkopieren! Praktische Informatik I, HWS 2009, Kapitel 10 Seite 25 java.util.LinkedList Multifunktionsdatenstruktur Kann verwendet werden als Stack, Queue, Liste, etc. Schnittstelle (u.a.): LinkedList<E> addFirst(E e) addLast(E e) E getFirst() E getLast() Intern nicht mit Arrays implementiert sondern als verkettete Liste (siehe Kapitel 12) Nicht ganz so effizient und schnell Praktische Informatik I, HWS 2009, Kapitel 10 Seite 26 HashMap und HashSet java.util.HashMap<K,V> Bildet Elemente des Typs K ab auf Elemente des Typs V K = Schlüssel (z.B. ein String), V = Wert (z.B. ein Objekt) “Hash Tabelle”, siehe Vorlesung “Algorithmen und Datenstrukturen” java.util.HashSet<E> Verwaltet “Mengen” des Typs E Elemente können nur ein Mal drin sein Kann effizient prüfen, ob ein Element enthalten ist Praktische Informatik I, HWS 2009, Kapitel 10 Seite 27 Historisches Sammlungen flexibler Größe sind sehr mächtig Im Vergleich mit Arrays fester Größe sind sie aber auch „langsamer“ Sammlungen flexibler Größe können auch keine primitiven Typen wie int speichern Java erlaubt keine generische Erzeugung von Arrays Arrays in Java behalten eine Syntax bei, die sich in anderen Programmiersprachen bereits durchgesetzt hat (vor allem in C/C++) Erleichtert Programmierern den Einstieg In Java-Syntax würde man heute wohl eher Array<int> statt int[] sagen Praktische Informatik I, HWS 2009, Kapitel 10 Seite 28 Zusammenfassung Sammlungen, generische Klassen Stapel, Stack ArrayList Iteratoren for each Queue, LinkedList, Map, Set Praktische Informatik I, HWS 2009, Kapitel 10 Seite 29