Know How
Listen von Wortkarten
Um das Spiel programmieren zu können, benötigt man eine Liste, in die man an beliebiger Stelle ein Wort einfügen oder löschen kann. Solch eine Liste kann man ähnlich implementieren, wie Du das vielleicht schon für Warteschlangen oder Stapel gemacht hast. Glücklicherweise müssen wir entsprechende Klassen aber nicht immer selbst programmieren, sondern können einfach entsprechende Klassen benutzen, die uns die benötigte Funktionalität schon fertig bieten.
LinkedList
Java stellt uns viele Klassen zur Verfügung, die wir einfach benutzen können.
Eine dieser Klassen hatten wir schon oft benutzt: String
.
Eine andere Klasse ist LinkedList
, die genau die Funktionalität,
die wir von einer Liste erwarten, schon fertig bereit stellt.
Daneben gibt es noch mehrere tausend anderer Klassen.
Damit die Vielzahl dieser Klassen geordnet werden können, wurden diese in
sogenannten Paketen organisiert.
Um eine Klasse benutzen zu können, muss man dann das entsprechende
Paket am Anfang des Quellcodes - noch vor der Definition der Klasse -
importieren.
Um z.B. die Klasse LinkedList
aus dem Paket java.util
benutzen zu können, muss man also
im Quellcode schreiben:
import java.util.LinkedList;
// oder um alle Klassen dieses Paketes zu importieren:
import java.util.*;
// Erst danach folgt die Definition der Klasse.
class MeineKlasse{
... hier kann LinkedList jetzt benutzt werden...
}
Wir gehen in den folgenden Beispielen von einer Klasse Hund
aus:
class Hund {
void bellen() {
System.out.println("Wuff!");
}
}
Innerhalb einer Methode ließe sich dann eine entsprechende Liste z.B. folgendermaßen benutzen:
// Definiere eine Variable und erzeuge eine neue LinkedList
LinkedList liste = new LinkedList();
// Erzeuge einen Hund, der an das Ende der Liste
// angehängt werden soll
Hund struppi = new Hund();
liste.add(struppi);
// oder mit anonymen Objekt
liste.add(new Hund());
// oder Einfügen an bestimmter Stelle
liste.add(1, new Hund());
// Entferne den zweiten Hund, Index ist 1 !!!
liste.remove(1);
// Gibt die Größe der Liste aus, hier: 2
System.out.println(liste.size());
// Gibt das erste Element zurück
Hund bello = liste.get(0);
// Die Liste leeren
liste.clear();
Generische Klassen
Möchte man auf Methoden der Klasse Hund
zugreifen,
erhält man eine Fehlermeldung:
import java.util.*;
LinkedList liste = new LinkedList();
liste.add(new Hund());
liste.get(0).bellen();
Error: cannot find symbol - method bellen()
Da man keine Angaben über den Typ der Listenelemente gemacht hat,
kann Java nur von der gemeinsamen Oberklasse Object
als Datentyp
ausgehen.
Objekte der Klasse Object
können aber natürlich nicht bellen.
Um diese Probleme zu vermeiden, kann man in Java generische Klassen (lat.: generalis=allgemein) benutzen. Diese werden auch parametrisierte Klassen genannt, weil zusätzlich zum Klassennamen noch weitere Datentypen - ähnlich wie Parameter einer Methode - angegeben werden.
Bei Objektsammlungen wird dies üblicherweise genutzt, um den Typ der Objekte in der Sammlung zu definieren:
// Definiere eine LinkedList von Hund(en)
// und weise ihr eine neue LinkedList von Hund zu
LinkedList<Hund> liste = new LinkedList<Hund>();
Man darf im Konstruktor den konkreten Typ weglassen, da er ja schon bei der Definition der Variablen angegeben wurde. Gleichwertig zu obigem Code ist also:
// Definiere eine LinkedList von Hund(en)
// und weise ihr eine neue LinkedList von Hund zu
LinkedList<Hund> liste = new LinkedList<>();
Man kann dann alle Methoden wie oben aufrufen, darf über z.B.
add
nur Objekte vom Typ Hund
zufügen und erhält bei Aufruf der Methode get
ein Objekt vom Typ Hund
.
Folgende Sequenz lässt sich im Codepad von BlueJ fehlerfrei ausführen:
import java.util.*;
LinkedList<Hund> liste = new LinkedList<Hund>();
liste.add(new Hund());
liste.get(0).bellen();
Listen durchlaufen
Möchte man alle Elemente einer Liste durchlaufen, kann man dies z.B. mit einer for-Schleife tun:
for(int i = 0; i < liste.size(); i++) {
liste.get(i).bellen();
}
Für solche einfachen Anwendungsfälle kann man alternativ auch die for-each-Schleife benutzen:
for(Typ name: sammlungsobjekt) {
...
}
Angewandt auf das obige Beispiel also:
for(Hund h: liste) { // Lies: Für jeden Hund h aus liste
h.bellen();
}