Lernziele
Zentrale Konzepte in diesem Kapitel: Sammlungen, Iteratoren, Schleifen
Java-Konstrukte in diesem Kapitel: ArrayList, Iterator, for-each-Schleife, while-Schleife, null, anonyme Objekte
4.1 Die Abstraktion Sammlung
Konzept
Sammlungen: Sammlungsobjekte sind Objekte, die eine beliebige Anzahl anderer Objekte enthalten können. z.B. in der Java-Bibliothek -> ArrayList
4.2 Eine Bibliotheksklasse verwenden
Klassenbibliotheken
Objektorientierte Sprachen sind unter anderem deshalb so mächtig, weil sie oft von Klassenbibliotheken begleitet werden. Diese Bibliotheken enthalten normalerweise viele Hunderte oder Tausende von verschiedenen Klassen, die sich bereits in zahlreichen Projekten als sehr nützlich für die Entwickler erwiesen haben, In Java heissen diese Bibliotheken Pakete, Bibliotheksklassen werden genauso verwendet wie eigene Klassen. Instanzen werden mit new erzeugt und die Klassen haben Datenfelder, Konstruktoren und Methoden
Wenn wir eine nützliche Klasse von einem anderen Programmierer übernehmen bezeichnet man diese als Bibliotheken von Drittanbietern (z.B. javazoom.net)
4.2.1 Eine Bibliotheksklasse importieren
import java.util.ArrayList;
Diese Anweisung macht die Klasse ArrayList aus dem Paket java.util innerhalb der Klassendefinition verfügbar.
Notes: import-Anweisungen müssen immer vor den Klassendefinitionen stehen. (Sprich im zu oberst)
So kann man die ArrayList, wie eine selbst definierte Klasse verwenden, indem wir ein Datenfeld definieren:
private ArrayList<String> dateien;
Notes: ArrayList ist eine allgemeine Sammlungsklasse (d.h eine Klasse, deren Speicherkapazität nicht beschränkt ist). Jedoch müssen wir mitgeben, welche Art von Objekten in dieser Speziellen Instanz gespeicher twerden soll. ( < > -> z. B. <String> ) Stichwort Generische Klasse
4.2.2 Diamant-Notation
// ist die Abkürzung für (siehe die letzte Codezeile)
dateien = new ArrayList<>();
dateien = new ArrayList<String>();
Dies ist die sogenannte Diamant-Notation (weil die beiden spitzen Klammern eine diamantähnliche Form bilden).
4.2.3 Schlüsselmethoden von ArrayList
Die Klasse ArrayList definiert etliche Methoden: Wir verwenden an dieser Stelle jedoch nur vier von Ihnen:
add, size, get und remove
- Mit der Methode add fügen wir ein Objekt in der ArrayList hinzu.
- Die Methode size liefert die Anzahl der bereits gespeicherten Elemente
- Die Methode get gibt ein Element zurück. Wichtig hier muss ein Index mitgeliefert werden
- Die Methode remove entfernt ein Element in der ArrayList. Auch hier muss ein Index mitgeliefert werden.
Notes: In einer Liste ist der Index-Startwert immer bei 0
4.3 Objektstrukturen mit Sammlungen
Um besser verstehen zu können, wie ein Sammlungsobjekt der Klasse ArrayList arbeitet, sollten wir ein Objektdiagramm betrachten:

Es gibt mindestens drei Eigenschaften der Klasse ArrayList, die auffallen sollten:
- Sie kann ihre interne Kapazität bei Bedarf vergrössern: Wenn weitere Objekte eingefügt werden, wird für diese einfach Platz geschaffen
- Sie führt Buch über die Anzahl der aktuell gespeicherten Elemente. Die Methode size liefert diese Anzahl.
- Sie behält die Reihenfolge bei, in der die Elemente eingefügt werden. Die add-Methode speichert jedes neue Element am Ende der Liste. Später können die Elemente in der gleichen Reihenfolge wieder aus der Liste herausgeholt werden.
4.4 Generische Klassen
Generische Klassen definieren, im Gegensatz zu allen bisher betrachteten Klassen, nicht einen einzelnen Tyo in Java, sondern potenziell viele Typen. Die Klasse ArrayList beispielsweise kann benutzt werden, um eine ArrayList von Strings, eine ArrayList von Personen etc. definieren. Jede ArrayList ist ein eigener Typ, der in der Deklaration von Datenfeldern, Parametern und Methodenerebignisse verwendet werden kann.
private ArrayList<Person> mitglieder;
private ArrayList<Ticketautomat> meineAutomaten;
Übung 4.1 Schreiben Sie die Deklaration eines privaten Datenfeldes bibliothek, das eine ArrayList halten kann. Die Elemente der ArrayList sollen vom Typ Buch sein.
private ArrayList<Buch> bibliothek;
Übung 4.2 Schreiben Sie die Deklaration einer lokalen Variablen cs101 die eine ArrayList von Student-Objekthält
Array<Student> cs101;
Übung 4.3 Schreiben Sie eine Deklataion eines privaten Datenfeldes tracks, um eine Sammlung von Musktrack-Objekten zu speichern.
private ArrayList<Musiktrack> tracks;
//oder
Array<Musiktrack> tracks;
Übung 4.4 Schreiben Sie Zuweisungen an die Variablen bibliothek, cs101 und tracks (die Sie in den drei vorangegangenen Übungen definiert haben)m um die entsprechenden ArrayList-Objekte zu erzeugen. Schreiben Sie sie einmal mit Diamant-Notation und einmal ohne, indem Sie den vollständigen Typ angeben.
biliothek = new ArrayList<Buch>();
cs101 = new ArrayList<Student>();
tracks = new ArrayList<Musiktrack>();
// Diamant Notation
biliothek = new ArrayList<>();
cs101 = new ArrayList<>();
tracks = new ArrayList<>();
4.5 Nummerierung in Sammlungen
ArrayList haben eine implizite Nummerierung oder Postion, beginnend mit 0 (Index).

Fallstrick
Bei nachlässiger Benutzung kann es Ihnen passieren, dass Sie einen Zugriff auf ein Element mit einem Index ausserhalb der gültigen Indexgrenzen einer ArrayList versuchen. In solchen Fällen erhalten Sie eine Fehlermeldung: Index-Grenzverletzung (IndexOutOfBoundException)
Übung 4.5 Wenn eine Sammlung 10 Elemente enthält, welchen Wert liefert dann ein Aufruf ihrer Methode size()?
Lösung: 10
Übung 4.6 Schreiben Sie eine Methode, die mithilfe der Methode get das fünfte Objekt in einer Sammlung mit dem Namen element liefert.
element.get(4);
Übung 4.7 Welchen Index hat das letzte Element in einer Sammlung von 15 Objekten?
Lösung: 14
Übung 4.8 Schreiben Sie eine Methode, die ein Objekt, auf das die Variable lieblingstrack verweist, in die Sammlung dateien einfügt.
dateien.add(lieblingstrack);
4.5.1 Elemente aus einer Sammlung entfernen
Die Klasse ArrayList bietet die Methode remove(int index) and. Eine Besonderheit beim Entfernen von Elementen ist, dass es die Indexwerte der restlichen in der Sammlung gespeicherten Objekt öndert. Wenn ein Element mit einer niederigen Indexnummer entfernt wird, dann verschiebt die Sammlung alle nachfolgenden Elemente um eine Postion (Minus um eine Position)
AusgangsLage:
import java.util.ArrayList;
/**
* Eine Klasse zur Verwaltung von Audiodateien.
*
* @author David J. Barnes und Michael Kölling.
* @version 2016.02.29
*/
public class MusikSammlung
{
// Eine ArrayList, in der die Namen von Audiodateien gespeichert werden können.
private ArrayList<String> dateien;
/**
* Erzeuge eine MusikSammlung.
*/
public MusikSammlung()
{
dateien = new ArrayList<>();
}
/**
* Füge der Sammlung eine Datei hinzu.
* @param dateiname die hinzuzufügende Datei
*/
public void dateiHinzufuegen(String dateiname)
{
dateien.add(dateiname);
}
/**
* Liefere die Anzahl der Dateien in dieser Sammlung.
* @return die Anzahl der Dateien in dieser Sammlung
*/
public int gibAnzahlDateien()
{
return dateien.size();
}
/**
* Gib eine Datei aus der Sammlung auf die Konsole aus.
* @param index der Index der Datei, deren Name ausgegeben werden soll
*/
public void dateiAusgeben(int index)
{
if(index >= 0 && index < dateien.size()) {
String dateiname = dateien.get(index);
System.out.println(dateiname);
}
}
/**
* Entferne eine Datei aus der Sammlung.
* @param index der Index der zu entfernenden Datei
*/
public void entferneDatei(int index)
{
if(index >= 0 && index < dateien.size()) {
dateien.remove(index);
}
}
}
Übung 4.9 Schreiben Sie eine Methode, die das dritte Objekt aus der Sammlung verabredungen entfernt
verabredungen.remove(2);
Übung 4.10 Nehmen Sie an, dass in einer Sammlung ein Objekt bei Index 6 gespeichert ist. Welchen Index wir dieses Objekt haben, nachdem die Objekte bei Index 0 und Index 9 entfernt wurden?
Index 0 wird entfernt -> Position 6 um eins verringern -> 5
Index 9 wird entfernt -> weiterhin Position 5
Übung 4.11Fügen Sie zu der Klassen MusikSammlung eine Methode indexPruefen hinzu. Diese Methode übernimmt einen int-Parameter und prüft, ob er ein gültiger Index für die aktuelle Sammlung ist. Um gültig zu sein, muss der Parameter im Bereich 0 bis size()-1 liegen.
Wenn der Parameter nicht gültig ist, sollte die Methode eine Fehlermeldung ausgeben, die Auskunft über den gültigen Indexbereich gibt. Ist der Index gültig, sollte nichts ausgegeben werden.
public void indexPruefen(int index)
{
if(index > dateien.size()-1 || index < 0)
{
System.out.println("Der Index muss im Bereich zwischen 0 - "+ (dateien.size()-1) +" liegen!");
}
}
Übung 4.12 Schreiben Sie eine alternative Version von indexPruefen namens gueltigerIndex. Diese Methode soll einen int-Parameter übernehmen und einen booleschen Wert zurückliefern. Sie gibt nichts aus, sondern liefert true zurück, wenn der Wert des Parameters ein gültiger Index für die aktuelle Sammlung ist, und andernfalls false.
public boolean gueltigerIndex(int index)
{
if(index > dateien.size()-1 || index < 0)
{
return false;
}
return true;
}
Übung 4.13 Ändern Sie die Methoden dateiAusgeben und entferneDatei in der Klasse MusikSammlung so, dass sie statt des booleschen Ausdrucks Ihre Methode gueltigerIndex verwenden, um ihren Parameter zu prüfen. Sie sollten nur dann get oder remove auf die ArrayList aufrufen, wenn gültigerIndex true zurückliefert.
/**
* Gib eine Datei aus der Sammlung auf die Konsole aus.
* @param index der Index der Datei, deren Name ausgegeben werden soll
*/
public void dateiAusgeben(int index)
{
if(gueltigerIndex(index)) {
String dateiname = dateien.get(index);
System.out.println(dateiname);
}
}
/**
* Entferne eine Datei aus der Sammlung.
* @param index der Index der zu entfernenden Datei
*/
public void entferneDatei(int index)
{
if(gueltigerIndex(index)) {
dateien.remove(index);
}
}
4.6 Komplette Sammlungen verarbeiten
4.6.1 Die for-each-Schleife (für jedes)
Die for-each Schleife ist eine Möglichkeit, eine Menge von Aktionen auf den Elementen einer Sammlung zu wiederholen, ohne dass die Aktionen mehrfach in den Quelltext geschrieben werden müssen.
Die Struktur einer for-each-Schleife kann durch folgenden Pseudecode dargestellt werden:
for ( Elementtyp element : sammlung)
{
// Schleifenrumpf
}
Notes: For-each ist eine bestimmte Iteration. Sprich man weiss genau wann sie aufhört.
Konzept
Eine Schleife kann benutzt werden, um einen Block von Anweisungen wiederholt ausführen zu lassen, ohne dass die Anweisungen mehrfach in den Quelltext geschrieben werden müssen.
Übung 4.14 Implementieren Sie die Methode alleDateienAusgeben.
public void alleDateienAusgeben()
{
for(String dateiName : dateien)
{
System.out.println(dateiName);
}
}
Übung 4.15 Zusatzaufgabe, Die for-each Schleife verwendet keine explizite int-Variable, um nacheinander auf die Elemente in der Liste zuzugreifen. Wenn wir als den Index von jedem Datinahme mit ausgeben wollen, mpssen wir unsere lokale int-Variable (z.B. position in der Methode deklarieren, sodass wir im Rumpf der Schleife in etwa Folgendes schreiben können:
System.out.println(postion + “: “+dateiName);
public void alleDateienAusgeben()
{
int position = 0;
for(String dateiName : dateien)
{
System.out.println(position + ": "+dateiName);
position++;
}
}
4.6.2 Eine Sammlung selektiv verarbeiten (mit If-Anweisungen)
Übung 4.15 Fügen Sie die Methode bestimmteDateienAusgeben. Vergewissern Sie sich , dass die Methode nur Dateien ausgibt, die dem Kriterium entsprechen.
Übung 4.15 Zusatzaufgabe. Gibt es in der Methode bestimmteDateienAusgeben eine Möglichkeit, nach Beenden der for-each-Schleife eine Nachricht auszugeben, die darüber informiert, dass kein Dateiname mti dem Suchbegriff übereinstimmt? Hinweis: Verwenden Sie eine lokale boolesche Variable.
TODO weitere übungen:
4.7 Unbestimmte Iteration
4.7.1 Die while-Schleife
Struktur einer while-schleife:
while(boolesche Bedingung){
// Schleifenrumpf
}
Die boolesche Bedingung steuert letztendlich, wie oft eine Schleife ausgeführt wird.
Übung 4.15 Angenommen, wir drücken die erste Version der Schlüsselsuche in Pseudocode wie folgt aus:
boolean fehlt = true;
while(fehlt){
if(die Schlüssel sind am nächsten Ort){
fehlt= false;
}
}
Versuchen Sie die zweite Version auszudrücken, indem Sie folgendes Gerüst vervollständigen:
boolean gefunden = false:
while(!gefunden)
{
if(Schlüssel sind am nächsten Ort){
gefunden = true;
}
}
Lösung ist fett markiert
Es gibt zwei Vorteile einer while-Schleife
- Eine while-Schleife muss nicht mit einer Sammlung verbunden sein. wir können Schleifen auf Basis jeder nur denkbaren Bedingung formulieren, die sich als boolescher Ausdruck schreiben lässt.
- Wir müssen, selbst wenn wir mit der Schleife eine Sammlung verarbeiten, nicht jedes Element verarbeiten. Somit können wir die Schleife bei Bedarf früher beenden. (Abbruchkriterium)
TODO Übungenm hinschreiben S159. & s162
4.8 Der Typ Iterator (generischer Typ)
Konzept
Ein Iterator ist ein Objekt, mit dessen Hilfe über alle Elemente einer Sammlung iteriert werden kann (d.h. alle Elemente durchlaufen werden können)
Notes: Iterator ist eine Java-Klasse
Die Methode iterator der Klasse ArrayList liefert ein Iterator Objekt. Iterator ist ebenfall im Paket java.util deklariert, entsprechend müssen wir folgende import-Anweisung in den Quelltext einfügen, um den Typ benutzen zu können
import java.util.Iterator;
Ein Iterator biete nur vier Methoden, von denen zwei verwendet werden, um über eine Sammlung zu iterieren: hasNext und next.
PseudoCode
Iterator<Elementyp> it = meineSammlung.iterator();
While (it.hasNext()){
// solange es noch ein weiteres Element gibt mit it.next() das nächste Element holen
// Etwas mit diesem Element tun
}
Beispielcode:
public void alleTracksAusgeben()
{
Iterator<Track> it = tracks.iterator();
while(it.hasNext()){
Track t = it.next();
System.out.println(t.gibDetails());
}
}
Vorteil von Iterator:
– Wir brauchen nicht mehr um die Indexierung zu kümmern. Iterator verwaltet diese Information selbst.
– Wir für alle Sammlungstypen der Java-Klassenbibliothek unterstützt.
– Um Elemente zu entfernen (in den anderen Methoden ist es komplizierter etwas zu entfernen ohne die Indexierung zu zerstören)
Iterator<Track> it = tracks.iterator();
while(it.hasNext()){
Track t = it.next();
String interpret = t.gibDetails();
if(interpret.contains("zuEntfernenderInterpret")){
it.remove();
}
}
Notes: Die dritte Methode lautet remove
4.9 Das Schlüsselwort null
Konzept
Das Java-Schlüsselwort null hat die Bedeutung “kein Objekt”. null wird in einer Objektvariablen gespeichert, die nicht auf ein konkretes Objekt verweist. Eine Objektvariable, die nicht explizit initialisiert wurde, enthält als Standardwert null.
4.10 Anonyme Objekte
Objekt direkt in der Methode erzeugen:
postliste.add(new Posten(naechstenPostennummer, beschreibung));
Zusammenfassung der Konzepte
- Sammlung Sammlungsobjekte sind Objekte, die eine beliebige Anzahl anderer Objekte enthalten können.
- Schleife Eine Schleife kann benutzt werden, um einen Block von Anweisungen wiederholt ausführen zu lassen, ohne dass die Anweisungen mehrfach in den Quelltext geschrieben werden müssen.
- Iterator Ein Iterator ist ein Objekt, mit dessen Hilfe über alle Elemente einer Sammlung iteriert werden kann.
- null Das Java-Schlüsselwort null hat die Bedeutung “kein Objekt”. null wird in einer Objektvariablen gespeichert, die nicht auf ein konkretes Objekt verweist. Eine Objektvariable, die nicht explizit initialisiert wurde, enthält als Standardwert null.
Kommentare