Java/List: Unterschied zwischen den Versionen

Aus ZUM-Unterrichten
main>ZUM-Wiki-Bot
(</source>)
(akt - Unterseiten in Lernpfad integriert)
Markierung: 2017-Quelltext-Bearbeitung
 
(5 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
{{Kurzinfo-3|Java|Links|Software}}
{{DISPLAYTITLE:(verkettete) Listen}}''
'''Verkettete Listen'''  gehören  zu  den  dynamischen  Datenstrukturen,  die  eine Speicherung  von einer im Vorhinein nicht bestimmten Anzahl von miteinander in Beziehung stehenden Werten einfacher oder zusammengesetzter Datentypen erlauben. 


==Erster Implementierungsansatz==
Eine Liste hat ein '''erstes Element''' (auch Knoten), dieses wird '''Kopf''' genannt. Eine Liste hat auch immer ein letztes Element. Im Gegensatz zum Array muss jedoch nicht festgelegt werden, wie groß die Liste letztlich sein wird. Ein Element einer Liste enthält Daten.  Im folgenden Bild sind dies Zahlen. In Java können nicht nur Zahlen in Listen gespeichert werden, '''beliebige Objekte können in Listen strukturiert''' werden.  
* ??? Wahrscheinlich ist der Positionszähler nicht so gemeint. Er soll anscheinend selbst ein Listenelement sein. Besitzt jemand einen stimmigen Quelltext?


===Mögliche Interpretation===
Die Listenart, die uns vornehmlich interessiert, ist eine '''doppelt verkettete Liste'''.<ref>Die Zentralabikonforme Liste ist doppelt verknüpft, das sie den Nachfolger und auch den Vorgänger kennt.</ref> Das bedeutet,dass von jedem Knoten aus das vorherige und das nachfolgende Element erreicht werden kann.
Realisiert mit ArrayList:
<source lang="java">
import java.util.ArrayList;


public class List {
[[Datei:Java-Liste-1.png|thumb|600px|left|verkettete Liste]]
private ArrayList liste;
{{clear}}
private int positionszeiger;
== Quiz ==
[[Datei:Java-Liste-Quiz.png|thumb|Übersicht über die Klasse Quiz]]
Ein nettes Beispiel für eine Liste ist ein Quiz. Auf Karteikarten stehen je­weils eine Frage und eine Antwort.
Die Klasse Quiz legt im Konstruktor 4 Bei­spielfragen an und legt sie als Liste ab  (<span style="color:red">bessere Formulierung?</span>).


public List(){
Die Methoden der Klasse Quiz verdeutlichen, wie man mit einer Liste umgehen kann. QuizGUI ist eine freiwillige Vertie­fung, auf die nicht näher einge­gangen wird.
  liste = new ArrayList(); // die Liste ist leer
  positionszeiger=-1; // der Positionszeiger steht vor der Liste
}


public void insertBefore (Object pObject)
=== Typecast: Object in Karteikarten wandeln ===
  liste.add(positionszeiger, pObject);
In der Klasse Quiz gibt es folgende Formulierung:
  positionszeiger--;
Karteikarte karte = (Karteikarte) liste.getItem();
}


public void insertBehind (Object pObject)
oder ausführlich:
  liste.add(positionszeiger+1, pObject);
Karteikarte karte;
}
karte = (Karteikarte) liste.getItem();


public void update (Object pObject)
Die Klammern um die Klasse Karteikarte drücken aus, dass der geholte Inhalt der Liste, der grundsätzlich vom Typ Objekt (in Java: ''Object'') ist, in eine Karteikarte umgewandelt wird. Es geschieht ein „Typecasting“ von Object zu Karteikarte.In der Liste lassen sich beliebige Objekte speichern. Das kann String, int, Konto, Karteikarte &hellip; sein. Möglich ist auch, dass in einer Liste verschiedene Objekte gespeichert werden (ein Konto und zwei Karteikarten). Allerdings muss man aufgrund dieser Flexibilität selbst dafür sorgen, dass die zurückgegebenen Objekte zu den gewünschten Typen umgewandelt werden, was im obigen Beispiel Karteikarte ist.
  liste.set(positionszeiger, pObject);
}


public void delete ()
{{Box|Arbeitshinweise|
  liste.remove(positionszeiger);
# Nennen Sie Methoden, die Sie selbst zum Führen von Listen benötigen würden (z.B. auf einer Adressliste <code>streicheDurch())</code>. Vergleichen Sie Ihre benötigten Methoden mit den Methoden der Klasse „List“, die auf den folgenden Seiten beschrieben werden.
}
# Analysieren Sie das Klassendiagramm und die Beschreibung zu „List“.<br>Veranschaulichen Sie die Methoden, indem Sie sich eine Liste als Güterzug vorstellen und den Positionszeiger als Kran, der immer nur auf einen Waggon zugreifen kann.
# Analysieren Sie das Quiz-Projekt. Schauen Sie sich zunächst die einfache Klasse Kartei­karte an. Analysieren Sie anschließend die Klasse Quiz.<br>Hinweis: <code>werteFragenAus()</code> sorgt dafür, dass Fragen mit falschen Antworten ans Ende der Liste gehängt werden.
# Schreiben Sie die Methode <code>steckeAktuelleKarteGanzNachHinten()</code>, die die aktuelle Karte ganz nach hinten schiebt. (analog: nach vorne)
# Schreiben Sie die Methode <code>bringeKarteUmEinePositionNachVorne()</code>, die die aktuelle Karte um eins nach vorne schiebt.
# Implementieren Sie die folgenden Methoden:
## <code>gibRueckwaertsAus()</code>, die ähnlich wie die Ausgabe alle Fragen auf der Konso­le ausgibt, diesmal aber rückwärts (letzte Frage zuerst).
## <code>gibLaengeDerListe()</code> , die eine int-Zahl mit der Anzahl der Listenelemente zurückgibt.
## <code>geheZuFrageNr(int x)</code>, die den Positionszeiger auf die x-te Frage setzt.
# Schreiben Sie die Methode <code>sucheFrage(String Antwort)</code>, die die Frage zu einer Antwort zurückgibt.|Arbeitsmethode}}


public void next(){
== Zuganzeigetafel ==
  if (positionszeiger!=liste.size()) positionszeiger++;
[[Datei:Bahnanzeige.png|right|325px||Zuganzeigetafel]]An  Bahnhöfen oder U-Bahn-Stationen gibt es seit einigen Jahren einen besonderen Service: Elektronische Hin­weisschilder zeigen die Züge an, die als nächstes abfahren werden. Dabei wird neben dem Ziel auch das Gleis, die Abfahrtszeit inkl. eventueller Verspätung erfasst. Diese Servicetafeln benötigen folgende Funktionalität:
}
'''Es gibt 3 verschiedene Ausgaberoutinen'''
# Alle erfassten Züge müssen angezeigt werden können
# Auf spezielle Tafeln können nur die nächsten 10 Züge angezeigt werden.
# Alle Züge, die an ein Gleis einfahren (z.B. Gleis 5), können angezeigt werden


public void previous(){
Zur Verwaltung gehören die folgenden Routinen:
  if (positionszeiger>-1) positionszeiger--;
# Die Verspätungszeit und die Gleisnummer können verändert werden
}
# Ein Zug kann komplett gestrichen werden (wenn er abgefahren ist oder ausfällt)
# Ein neuer Zug kann eingefügt werden, dabei wird automatisch erkannt, an welche Position ergehört. Fährt er später ab als alle anderen, so wird er ans Ende der Liste gehängt.<br>Zusatz:
# Ist für ein Gleis die identische Abfahrtszeit angegeben, soll ein Warnhinweis angezeigt werden.
# Der nächste Zug, der abfährt, soll bei der Ausgabe mit einem Stern versehen werden.


public void toFirst(){
{{Box|Arbeitshinweise|# Lesen Sie zunächst alleine die Aufgabenbeschreibung und überlegen Sie sich grob eine Realisierung.
  positionszeiger=0;
# Diskutieren Sie in Ihrer Entwicklergruppe, welche Eigenschaften und Methoden die Klasse „Zug“ enthalten muss. Einigen Sie sich auf eine Variante, die dann für alle gilt. Fixieren Sie diese als UML-Diagramm.
}
# Teilen Sie sich die Arbeit auf. Wählen Sie einen Projektkoordinator, der die Übersicht über das Projekt erhält. An seinem Rechner werden die einzelnen Programmteile zu­sammengefügt.  Implementieren Sie das Projekt.|Arbeitsmethode}}


public void toLast(){
;Benötigt:
  positionszeiger=liste.size()-1;
* Liste, while, if...else, boolean, int, double
}
* [[BlueJ]], daher ohne main-Methode
;Hinweis:
Zur Vereinfachung der Aufgabe wird die Zeit als double erfasst. Das kann zu Problemen führen, wenn man Zeiten addieren möchte (z.B. Einrechnen der Verspätung).


public Object getItem(){
  if (liste.size()==0 || positionszeiger==-1 || positionszeiger>=liste.size())
    return null;
  else return liste.get(positionszeiger);
}


public boolean isEmpty (){ 
  return (liste.size()==0);
}


public boolean isBefore (){ 
=== Einfügemethode ===
  return (positionszeiger<0);
Die Einfügemethode für einen Zug funktioniert wie folgt:
}
(Der Algorithmus ist nicht unbedingt optimal, aber so ist er noch einfach zu verstehen)


public boolean isBehind (){ 
  return (positionszeiger>=liste.size());
}


}
<source lang="java">
    public void fügeZugHinzu(Zug pZug){
        if (zugliste.isEmpty()) {
            zugliste.insertBehind(pZug);
        }
        else {
            Zug zwischenspeicher;
            zugliste.toFirst();
            boolean schonEingefügt=false;
            while (!zugliste.isBehind() && !schonEingefügt){
                zwischenspeicher = (Zug) zugliste.getItem();
                if (zwischenspeicher.getAbfahrtzeit()>=pZug.getAbfahrtzeit()){
                    zugliste.insertBefore(pZug);
                    schonEingefügt=true;
                }
                zugliste.next();
            }
            if (!schonEingefügt) zugliste.insertBefore(pZug);
        }
    }
</source>
</source>


;Korrekturen:
{{Übung|
11.09. - insertBehind: Positionszeiger wird vor und zurück gestellt
# Weshalb wird <code>zwischenspeicher</code> angelegt? Welche Funktion hat <code>schonEingefügt</code>?
http://informatik.zum.de/pieper/blog/index.php?entry=entry060828-105313
# Gliedern Sie den Algorithmus:
#* a) Behandlung einer leeren Liste
#* b) Suchen der Position, an der eingefügt werden soll
#* c) Behandlung am Ende Einfügen
# Implementieren Sie als Methode der Verwaltung <code>gibZügeAus(int zahl)</code>, die <code>zahl</code> Züge mit einer laufenden Nummer, der Abfahrtszeit, des Ziels und der Gleisnummer ausgibt. Gehen Sie sinnvoll mit dem Problem um, dass <code>zahl</code> größer sein kann als die eingetragenen Züge.
#* Bsp:
#* 1.  14.39  Hamburg Gleis 5
#* 2.   17.29  Bonn Gleis 2
#Freiwilliger Zusatz: Schreiben Sie die Methode <code>streicheZugNr (int zahl)</code>, die den Listeneintrag Nummer <code>zahl</code> entfernt.  
}}


==Zweiter Implementierungsansatz OOP pur==
=== Quelltext  ===
* ??? Wahrscheinlich ist der Positionszeiger aus Delphi entlehnt und nicht sauber auf Java übertragbar. Hier mein Versuch es mit möglichst reinem OOP zu versuchen (bitte auf die Basisklasse ListElement achten).
Neben [[Java/List|class List]] sind folgende Klassen erforderlich.


<source lang="java">
<source lang="java">
import java.io.FileInputStream;
public class Zug {
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;


/**
  // Eigenschaften
* '''Bestandteil des Zentralabiturs 2009'''<br>
  private double abfahrtzeit;
* <br>
  private double verspätung;
* Objekte der Klasse List verwalten beliebige Objekte nach einem Listenprinzip. Ein
  private int gleisnummer;
* interner Positionszeiger wird durch die Listenstruktur bewegt, seine Position markiert
  private String zugBezeichnung;
* ein aktuelles Objekt. Die Lage des Positionszeigers kann abgefragt, verändert und die
  private String ankunftsBahnhof;
* Objektinhalte an den Positionen können gelesen oder verändert werden. Die Klasse Stack
  // Ende Variablen
* stellt Methoden in folgender Syntax zur Verfügung:
* <ul>
* <li>public List()</li>
* <li>public boolean isEmpty()</li>
* <li>public boolean isBefore()</li>
* <li>public boolean isBehind()</li>
* <li>public void next()</li>
* <li>public void previous()</li>
* <li>public void toFirst()</li>
* <li>public void toLast()</li>
* <li>public Object getItem()</li>
* <li>public void update (Object pObject)</li>
* <li>public void insertBefore (Object pObject)</li>
* <li>public void insertBehind (Object pObject)</li>
* <li>public void delete()</li>
* </ul>
* ''' Nicht Bestandteil des Zentralabiturs 2009''' - dient der praktischen Anwendung<br>
* <ul>
* <li>public clone()</li>
* <li>public load(String fileName)</li>
* <li>public save(String fileName)</li>
* </ul>
*
* @author <a href="mailto:schule@dinro.de">DiNaro</a>
* @version 1.0z+ 2006-09-12
*/
public class List implements Cloneable, Serializable
{
/**
* Attribut dient zur Serialisierung.
*/
private static final long serialVersionUID = 1087406856309777647L;
/**
* Attribut der Positionszeiger befindet sich vor der Liste (Flag).
*/
private boolean before;


/**
  public Zug (double pAbfahrtzeit, double pVerspätung, int pGleisnummer, String pZugBezeichnung, String pAnkunftsBahnhof){
* Attribut der Positionszeiger befindet sich hinter der Liste (Flag).
    abfahrtzeit= pAbfahrtzeit;
*/
    verspätung = pVerspätung;
private boolean behind;
    gleisnummer = pGleisnummer;
    zugBezeichnung = pZugBezeichnung;
    ankunftsBahnhof = pAnkunftsBahnhof;
  }
 
  // Methoden
  public String getAnkunftsBahnhof() {
    return ankunftsBahnhof;
  }


/**
  public void setAnkunftsBahnhof(String ankunftsBahnhof) {
* Attribut aktuelles Element.
    this.ankunftsBahnhof = ankunftsBahnhof;
*/
  }
private ListElement current;


/**
  public String getZugBezeichnung() {
* Attribut erstes Element der Liste
    return zugBezeichnung;
*/
  }
private ListElement first;


/**
  public void setZugBezeichnung(String zugBezeichnung) {
* Attribut letztes Element der Liste.
    this.zugBezeichnung = zugBezeichnung;
*/
  }
private ListElement last;


/**
   public int getGleisnummer() {
* Der Konstruktor erzeugt eine leere lineare Liste.<br>
    return gleisnummer;
* <br>
  }
*
* <pre>
* Konstruktor   List()
* <br>
* Nachher      Eine leere Liste ist angelegt.
*              Der interne Positionszeiger steht vor der leeren Liste.
* </pre>
*/
public List()
{
this.first = null;
this.last = null;
this.current = null;
this.before = true;
this.behind = false;
}


/**
  public void setGleisnummer(int gleisnummer) {
* Kopiert die Liste - '''Nicht Bestandteil des Zentralbiturs 2009!!!'''<br>
    this.gleisnummer = gleisnummer;
* ("shallow copy" nach dem Handbuch der Java Programmierung Kapitel 9.4.2).
  }
*
* @return kopierte lineare Liste
* @throws CloneNotSupportedException kann nicht auftreten, aber der Compiler will es
*          so...
*/
@Override
public List clone() throws CloneNotSupportedException
{
try
{
return (List) super.clone();// "shallow copy"
}
catch (CloneNotSupportedException e)
{ // Kann nicht auftreten, aber der Compiler will es so...
throw new CloneNotSupportedException(e.toString());
}
}


/**
  public double getVerspätung() {
* Löscht des aktuellen Listenelement.<br>
    return verspätung;
* <br>
  }
*
* <pre>
* Auftrag      delete()
* Vorher      Der Positionszeiger steht nicht vor oder hinter der Liste.
* Nachher      Das aktuelle Listenelement ist gelöscht. Der Positionszeiger steht auf
*              dem Element hinter dem gelöschten Element, bzw. hinter der Liste,
*              wenn das gelöschte Element das letzte Listenelement war.
* </pre>
*/
public void delete()
{
if (!this.before && !this.behind)
{ // Zeiger des Vorgängerelementes setzen
if (this.current == this.first)
{ // Vorgänger existiert nicht - Kopfzeiger korregieren
this.first = this.current.getNext();
}
else
{ // Vorgänger existiert
this.current.getPrevious().setNext(this.current.getNext());
}
// Zeiger des Nachfolgerelementes setzen
if (this.current == this.last)
{ // Nachfolger existiert nicht - Scxhwanzzeiger korreegieren
this.last = this.current.getPrevious();
}
else
{ // Nachfolger existiert
this.current.getNext().setPrevious(this.current.getPrevious());
}
// aktuelles Element setzen
this.current = this.current.getNext();
// Flag für Positionszeiger befindet sich hinter der Liste setzen
this.behind = this.current == null;
}
}


/**
  public void setVerspätung(double verspätung) {
* Gibt den Inhalt des aktuellen Listenelementes zurück, ohne die Liste zu verändern.<br>
    this.verspätung = verspätung;
* <br>
  }
*
* <pre>
* Anfrage      getItem(): Object
* Nachher      Die Anfrage liefert den Wert des aktuellen Listenelements bzw. null,
*              wenn die Liste keine Elemente enthält, bzw. der Positionszeiger
*              vor oder hinter der Liste steht.
* </pre>
*
* @return item Inhalt des aktuellen Listenelementes.
*/
public Object getItem()
{
if (this.current != null)
{
return this.current.getItem();
}
else
{
return null;
}
}


/**
  public double getAbfahrtzeit() {
* Einfügen eines Listenelementes vor das aktuelle.<br>
    return abfahrtzeit;
* <br>
  }
*
* <pre>
* Auftrag      insertBefore (Object pObject)
* Vorher        Der Positionszeiger steht nicht vor der Liste.
* Nachher      Ein neues Listenelement mit dem entsprechenden Objekt ist angelegt und
*              vor der aktuellen Position in die Liste eingefügt worden.
*              Der Positionszeiger steht hinter dem eingefügten Element.
* </pre>
*
* @param pObject Inhalt des Listenelementes.
*/
public void insertBefore(Object pObject)
{
if (!this.before)
{ // Der Positionszeiger steht nicht vor der Liste.
ListElement newElement;
if (this.isEmpty())
{ // Erstes und einziges Element in die Liste einfügen
newElement = new ListElement(pObject, null, null);
this.first = newElement;
this.last = newElement;
this.behind = true;
this.current = null;
}
else
{ // Die Liste ist nicht leer
if (this.behind)
{ // Der Positionszeiger steht hinter der Liste
newElement = new ListElement(pObject, this.last, null);
this.last.setNext(newElement);
this.last = newElement;
this.behind = true;
this.current = null;
}
else
{ // Der Positionszeiger steht mitten in der Liste
newElement = new ListElement(pObject, this.current.getPrevious(), this.current);
if (this.current == this.first)
{ // Vorgänger existiert nicht - Kopfzeiger korregieren
this.first = newElement;
}
else
{ // Vorgänger koregieren
this.current.getPrevious().setNext(newElement);
}
// Nachfolger korregieren
this.current.setPrevious(newElement);
// Aktuelles Element bleibt aktuelles Element
}
}
}
}


/**
  public void setAbfahrtzeit(double abfahrtzeit) {
* Einfügen eines Listenlementes hinter das aktuelle.<br>
    this.abfahrtzeit = abfahrtzeit;
* <br>
  }
*
* <pre>
* Auftrag      insertBehind (Object pObject)
* Vorher        Der Positionszeiger steht nicht hinter der Liste.
* Nachher      Ein neues Listenelement mit dem entsprechenden Objekt ist angelegt
*              und hinter der aktuellen Position in die Liste eingefügt worden. Der
*              Positionszeiger steht vor dem eingefügten Element.
* </pre>
*
* @param pObject Inhalt des Listenelementes.
*/
public void insertBehind(Object pObject)
{
if (!this.behind)
{ // Der Positionszeiger steht nicht hinter der Liste.
ListElement newElement;
if (this.isEmpty())
{// Erstes und einziges Element in die Liste einfügen
newElement = new ListElement(pObject, null, null);
this.first = newElement;
this.last = newElement;
this.before = true;
this.current = null;
}
else
{ // Die Liste ist nicht leer
if (this.before)
{ // Der Positionszeiger steht vor der Liste.
newElement = new ListElement(pObject, null, this.first);
this.first.setPrevious(newElement);
this.first = newElement;
this.before = true;
this.current = null;
}
else
{ // Der Positionszeiger steht mitten in der Liste.
newElement = new ListElement(pObject, this.current, this.current.getNext());
if (this.current == this.last)
{ // Nachfolger existiert nicht - Schwanzzeiger korregieren
this.last = newElement;
}
else
{ // Nachfolger korregieren
this.current.getNext().setPrevious(newElement);
}
// Vorgänger koregieren
this.current.setNext(newElement);
// Aktuelles Element bleibt aktuelles Element
}
}
}
}


/**
  // Ende Ereignisprozeduren
* Steht der Positionszeiger vor der Liste?<br>
}
* <br>
</source>
*
* <pre>
* Anfrage      isBefore(): boolean
* Nachher      Die Anfrage liefert den Wert true, wenn der Positionszeiger vor dem
*              ersten Listenelement oder vor der leeren Liste steht, sonst liefert
*              sie den Wert false.
* </pre>
*
* @return liefert den Wert true, wenn der Positionszeiger vor dem ersten Listenelement
*        oder vor der leeren Liste steht, sonst liefert sie den Wert false.
*/
public boolean isBefore()
{
return this.before;
}


/**
<source lang="java">
* Steht der Positionszeiger hinter der Liste?<br>
public class Verwaltung
* <br>
{
*
    private List zugliste;
* <pre>
   
* Anfrage      isBehind(): boolean
    public Verwaltung()
* Nachher      Die Anfrage liefert den Wert true, wenn der Positionszeiger hinter dem
    { 
*              letzten Listenelement oder hinter der leeren Liste steht, sonst liefert
        zugliste=new List();
*              sie den Wert false.
        Zug zug=new Zug(12.05,20,5,"ICE","Lummerland");
* </pre>
        fügeZugHinzu(zug);
*
        zug=new Zug(11.11,10,2,"RE","Nimmerland");
* @return liefert den Wert true, wenn der Positionszeiger hinter dem letzten
        fügeZugHinzu(zug);
*         Listenelement oder hinter der leeren Liste steht, sonst liefert sie den Wert
        zug=new Zug(13.44,20,5,"RB","Sibirien");
*         false.
        fügeZugHinzu(zug);
*/
        zug=new Zug(12.14,20,5,"RB","Entenhausen");
public boolean isBehind()
        fügeZugHinzu(zug);
{
        zug=new Zug(17.30,20,2,"S-Bahn","Hansaring");
return this.behind;
         fügeZugHinzu(zug);       
}
    }
   
    public void fügeZugHinzu(Zug pZug){
         if (zugliste.isEmpty()) {
            zugliste.insertBehind(pZug);
        }
        else {
            Zug zwischenspeicher;
            zugliste.toFirst();
            boolean schonEingefügt=false;
            while (!zugliste.isBehind() && !schonEingefügt){
                zwischenspeicher = (Zug) zugliste.getItem();
                if (zwischenspeicher.getAbfahrtzeit()>=pZug.getAbfahrtzeit()){
                    zugliste.insertBefore(pZug);
                    schonEingefügt=true;
                }
                zugliste.next();
            }
            if (!schonEingefügt) zugliste.insertBefore(pZug);  
        }
    }
   
}
</source>


/**
== Implementation der NRW-Zentralabi-Liste ==
* Enthält die Liste keine Elemente?<br>
Die '''Zahlenliste''' ist wohl eine der einfachsten Anwendungen der Liste. In der Realität kommen Zahlenlisten z.B. bei der Erfassung von Aktienkursen (DAX-Tafel) oder bei der Fieberkurve im Krankenhaus vor.
* <br>
Die folgende Liste basiert verwendet [[Java/List|List]].
*
* <pre>
* Anfrage      isEmpty(): boolean
* Nachher      Die Anfrage liefert den Wert true, wenn die Liste keine Elemente
*              enthält, sonst liefert sie den Wert false.
* </pre>
*
* @return liefert den Wert true, wenn die Liste keine Elemente enthält, sonst liefert
*        sie den Wert false.
*/
public boolean isEmpty()
{
return this.first == null;
}


/**
* Lädt die gesamte Liste als Objekt aus einer Datei - <b>Nicht Bestandteil des
* Zentralbiturs 2009!!!</b><br>
* Neues aktuelles Element wird das erste Listenelement(Setzung!).
*
* @param fileName [Laufwerk][Pfad]Dateiname,
* @throws ClassNotFoundException Erwartete Klasse nicht vorhanden
* @throws IOException Fehler beim Laden der Datei
*/
public void load(final String fileName) throws ClassNotFoundException, IOException
{
try
{
final ObjectInputStream stream = new ObjectInputStream(
new FileInputStream(fileName));
final List dummy = (List) stream.readObject();
this.first = dummy.first;
this.last = dummy.last;
this.before = dummy.before;
this.behind = dummy.behind;
this.toFirst(); // Als neues aktuelles Element wird das erste Listenelement gesetzt!
stream.close();
}
catch (final ClassNotFoundException e)
{ // Erwartete Klasse nicht vorhanden.
throw new ClassNotFoundException(e.toString());
}
catch (final IOException e)
{ // Fehler beim Laden der Datei.
throw new IOException(e.toString());
}
}


/**
* Setze das aktuelle Listenelement auf das nächste. <br>
* <br>
*
* <pre>
* Auftrag      next()
* Nachher      Der Positionszeiger ist um eine Position in Richtung Listenende weiter-
*              gerückt, d.h. wenn er vor der Liste stand, wird das Element am
*              Listenanfang zum aktuellen Element, ansonsten das jeweils nachfolgende
*              Listenelement. Stand der Positionszeiger auf dem letzten Listenelement,
*              befindet er sich jetzt hinter der Liste. Befand er sich hinter der
*              Liste, hat er sich nicht verändert.
* </pre>
*/
public void next()
{
if (!this.isEmpty())
{
if (this.before)
{ // Der Positionszeiger steht vor der Liste; das erste Element wird aktuelles
this.current = this.first;
this.before = false;
}
else
{ // der Positionszeiger steht nicht vor der Liste
if (this.current != null)
{ // das jeweils nachfolgende Listenelement wird aktuelles
this.current = this.current.getNext();
if (this.current == null)
{ // Der Positionszeiger zeigt hinter das letzte Element
this.behind = true;
}
}
} // Der Positionszeiger befindet sich hinter der Liste und bleibt unverändert
}
}


/**
<source lang="java">
* Setze das aktuelle Listenelement auf das vorherige.<br>
public class ZahlenListe
* <br>
{
*
    // Eigenschaften
* <pre>
    private List temperaturListe;
* Auftrag      previous()
 
* Nachher      Der Positionszeiger ist um eine Position in Richtung Listenanfang
    // Konstruktor
*              weitergerückt, d.h. wenn er hinter der Liste stand, wird das Element am
    // Legt eine Liste an und füllt sie mit einigen Beispielwerten.
*              Listenende zum aktuellen Element, ansonsten das jeweils vorhergehende
    public ZahlenListe()
*              Listenelement. Stand der Positionszeiger auf dem ersten Listenelement,
    {
*              befindet er sich jetzt vor der Liste. Befand er sich vor der Liste, hat
        temperaturListe = new List();
*              er sich nicht verändert.
        temperaturListe.insertBehind(2);
* </pre>
        temperaturListe.insertBehind(15);
*/
        temperaturListe.insertBehind(8);
public void previous()
        temperaturListe.insertBehind(4);
{
        temperaturListe.insertBehind(1);
if (!this.isEmpty())
        temperaturListe.insertBehind(6);
{ /// Der Positionszeiger bleibt unverändert, wenn die Liste leer ist
        temperaturListe.insertBehind(5);
if (this.behind)
 
{ // Der Positionszeiger steht hinter der Liste; das letzte Element wird aktuelles
    }
this.current = this.last;
   
this.behind = false;
    public void ausgebenDerListe(){
}
        temperaturListe.toFirst();
else
        while (!temperaturListe.isBehind()){
{// Der Positionszeiger steht nicht hinter der Liste
            Integer wert= (Integer) temperaturListe.getItem();
if (this.current != null)
            System.out.println (wert);
{ // das jeweils vorhergehende Listenelement wird aktuelles
            temperaturListe.next();
this.current = this.current.getPrevious();
        }
if (this.current == null)
        System.out.println ("Ende der Liste");
{ // Der Positionszeiger zeigt vor das erste Element
    }
this.before = true;
   
}
    public void neueZahl(int pZahl){
}
    temperaturListe.toLast();   
} // Der Positionszeiger befindet sich vor der Liste und bleibt unverändert
    temperaturListe.insertBehind(pZahl);
}
    }
}
 
    public void tauscheErsteBeidenZahlen(){
        temperaturListe.toFirst();
        Integer wert= (Integer) temperaturListe.getItem();
        temperaturListe.next();
        Integer wert2= (Integer) temperaturListe.getItem();
        temperaturListe.update(wert);
        temperaturListe.previous();
        temperaturListe.update(wert2);
    }  
   
    // Ausgeben der höchsten Zahl
    public void gibGrößteZahlAus () {
        temperaturListe.toFirst();
        Integer wert= (Integer) temperaturListe.getItem();
        while (!temperaturListe.isBehind()){
            if (wert<(Integer) temperaturListe.getItem()) {
                wert = (Integer) temperaturListe.getItem();
            }
            temperaturListe.next();
        }
        System.out.println(wert+" ist die größte Zahl");
    }
   
    // Summiere alle Zahlen und gib die Summe zurück
    public int gibSummeZahlZurück () {
        temperaturListe.toFirst();
        int zwischenspeicher;
        zwischenspeicher = 0;
        while (!temperaturListe.isBehind()){
            zwischenspeicher += (Integer) temperaturListe.getItem();
            temperaturListe.next();
        }
        return zwischenspeicher;
    }
   
 
}
</source>
 
 
=== NRW-Zentralabi-Liste mit GUI ===
* Der folgende Quelltext verwendet die Klasse List (NRW-Zentralabitur).
* Die Klasse GUI wurde erstellt mit [[Netbeans]] - BlueJ-Edition.


/**
{{Übung|
* Speichert die gesamte Liste als Objekt in einer Datei - <b>Nicht Bestandteil des
* Testen Sie den GUI-Ersteller von Netbeans. Nennen Sie Vor- und Nachteile relativ zur "Handarbeit".
* Zentralbiturs 2009!!!</b><br>
* Analysieren Sie die Methoden zu den Buttons.
* Das aktuelles Element bleibt erhalten!
* Wie oft muss man den "Sortieren-Button" drücken, bis die Liste spätestens sortiert ist? (Wie könnte man das automatisieren?).
*
* Beschreiben Sie die Funktionsweise der rekursiven Ausgabe.
* @param fileName [Laufwerk][Pfad]Dateiname.
* Fügen Sie einen Button hinzu: <code>größteZahl()</code>, die den größten Listenwert ermittelt und in der Textzeile ausgibt.
* @throws IOException Fehler beim Speichern der Datei
}}
*/
public void save(String fileName) throws IOException
{
try
{
ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream(fileName));
stream.writeObject(this);
stream.close();
}
catch (IOException e)
{ // Fehler beim Speichern der Datei.
throw new IOException(e.toString());
}
}


/**
* Setzt das aktuelle Listenelement auf das erste zurück.<br>
* <br>
*
* <pre>
* Auftrag      toFirst()
* Nachher      Der Positionszeiger steht auf dem ersten Listenelement.
*              Falls die Liste leer ist befindet er sich jetzt hinter der Liste.
* </pre>
*/
public void toFirst()
{
this.current = this.first;
this.before = false;
this.behind = this.isEmpty();
}


/**
[[Bild:ListeGUI.gif]]
* Setzt das aktuelle Listenelement auf das letzte zurück.<br>
* <br>
*
* <pre>
* Auftrag      toLast()
* Nachher      Der Positionszeiger steht auf dem letzten Listenelement.
*              Falls die Liste leer ist befindet er sich jetzt vor der Liste.
* </pre>
*/
public void toLast()
{
this.current = this.last;
this.behind = false;
this.before = this.isEmpty();
}


/**
* <pre>
* Auftrag      update (Object pObject)
* Vorher        Die Liste ist nicht leer. Der Positionszeiger steht nicht vor oder
*              hinter der Liste.
* Nachher      Der Wert des Listenelements an der aktuellen Position ist durch pObject
*              ersetzt.
* </pre>
*
* @param pObject neuer Wert des Listenelements
*/
public void update(Object pObject)
{ // Die Liste ist nicht leer. Der Positionszeiger steht nicht vor oder hinter der
// Liste.
if (!this.isEmpty() && !this.before && !this.behind)
{ // Die Liste ist nicht leer. Der Positionszeiger steht nicht vor oder hinter der Liste.
this.current.setItem(pObject);
}
}


}
<source lang="java">
////////////////////////////////// Basisklasse ListElement /////////////////////////////////
/*
import java.io.Serializable;
* GUI.java
*
* Created on 20. November 2006, 22:07
*/


/**
/**
* Datei ListElement.java (Klasse Listelement mit generalisiertem Datentyp Object).<br>
* <br>
* Die Klasse ListElement ist die '''Basisklasse für doppelt verkette Listen'''.<br>
* <br>
* Ein ListElement enthält eine Date, einen Verweis auf den Vorgänger und einen Verweis
* auf den Nachfolger. <br>
  *
  *
* Die Klasse ist wegen der Speicherbarkeit der Oberklasse serialisiert.<br>
  * @author  ugh
* '''Die Klasse ist nicht Bestandteil des Zentralabiturs 2009, aber notwendig!!!'''
*
  * @author <a href="mailto:schule@dinro.de">DiNaro</a>
  * @version 1.0z+ 2006-09-11
  */
  */
public class ListElement implements Serializable
public class GUI extends javax.swing.JDialog {
{
   
/**
    private List liste;
* Attribut dient zur Serialisierung.
   
*/
    /** A return status code - returned if Cancel button has been pressed */
private static final long serialVersionUID = 8626283657638014888L;
    public static final int RET_CANCEL = 0;
    /** A return status code - returned if OK button has been pressed */
    public static final int RET_OK = 1;
   
    /** Creates new form GUI */
    public GUI(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
        liste = new List();
        jTextArea1.setText("Leere Liste\nBitte füge etwas hinzu.");
    }
   
    /** @return the return status of this dialog - one of RET_OK or RET_CANCEL */
    public int getReturnStatus() {
        return returnStatus;
    }
   
    /** This method is called from within the constructor to
    * initialize the form.
    * WARNING: Do NOT modify this code. The content of this method is
    * always regenerated by the Form Editor.
    */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {
        okButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();
        jTextField1 = new javax.swing.JTextField();
        jButton1 = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();
        jButton4 = new javax.swing.JButton();
        jButton5 = new javax.swing.JButton();
        jButton6 = new javax.swing.JButton();
 
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                closeDialog(evt);
            }
        });
 
        okButton.setText("OK");
        okButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                okButtonActionPerformed(evt);
            }
        });
 
        cancelButton.setText("Cancel");
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });
 
        jTextField1.setText("6");
 
        jButton1.setText("add (am Ende)");
        jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton1MouseClicked(evt);
            }
        });
 
        jTextArea1.setColumns(20);
        jTextArea1.setRows(5);
        jScrollPane1.setViewportView(jTextArea1);


/**
        jButton2.setText("remove (Anfang)");
* Attribut Date des Listenelements.
        jButton2.addMouseListener(new java.awt.event.MouseAdapter() {
*/
            public void mouseClicked(java.awt.event.MouseEvent evt) {
private Object item;
                jButton2MouseClicked(evt);
            }
        });


/**
        jButton3.setText("remove (Ende)");
* Attribut Nachfolger des Listenelements.
        jButton3.addMouseListener(new java.awt.event.MouseAdapter() {
*/
            public void mouseClicked(java.awt.event.MouseEvent evt) {
private ListElement next;
                jButton3MouseClicked(evt);
            }
        });


/**
        jButton4.setText("rekursive Ausgabe");
* Attribut Vorgänger des Listenelements.
        jButton4.addMouseListener(new java.awt.event.MouseAdapter() {
*/
            public void mouseClicked(java.awt.event.MouseEvent evt) {
private ListElement previous;
                jButton4MouseClicked(evt);
            }
        });


/**
        jButton5.setText("add Zufallszahl");
* Der Konstruktor erzeugt ein Listenelement mit Date, Vorgänger und Nachfolger.
        jButton5.addMouseListener(new java.awt.event.MouseAdapter() {
*
            public void mouseClicked(java.awt.event.MouseEvent evt) {
* @param item Date des Listenelements.
                jButton5MouseClicked(evt);
* @param previous Vorgänger des Listenelements
            }
* @param next Nachfolger des Listenelemente.
        });
*/
public ListElement(Object item, ListElement previous, ListElement next)
{ this.item = item;
this.previous = previous;
this.next = next;
}


/**
        jButton6.setText("sortiere");
* Gibt die Date des Elements zurück.
        jButton6.addMouseListener(new java.awt.event.MouseAdapter() {
* @return  Date des Listenelements.
            public void mouseClicked(java.awt.event.MouseEvent evt) {
*/
                jButton6MouseClicked(evt);
public Object getItem()
            }
{ return this.item;
        });
}


/**
        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
* Gibt den Nachfolger des Listenelements zurück.
        getContentPane().setLayout(layout);
* @return    Nachfolger des Listenelements.
        layout.setHorizontalGroup(
*/
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
public ListElement getNext()
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
{ return this.next;
                .addContainerGap()
}
                .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 234, Short.MAX_VALUE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jButton6, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE)
                    .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                        .add(layout.createSequentialGroup()
                            .add(okButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 67, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                            .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                            .add(cancelButton))
                        .add(jTextField1))
                    .add(jButton4, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE)
                    .add(jButton3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE)
                    .add(jButton2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE)
                    .add(jButton5, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE)
                    .add(jButton1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE))
                .addContainerGap())
        );


/**
        layout.linkSize(new java.awt.Component[] {cancelButton, okButton}, org.jdesktop.layout.GroupLayout.HORIZONTAL);
* Gibt den Vorgänger des Listenelements zurück.
* @return  Vorgänger des Listenelements.
*/
public ListElement getPrevious()
{ return this.previous;
}


/**
        layout.setVerticalGroup(
* Setzt die Date des Listenelements.
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
* @param item    neue Date des Listenelements.
            .add(layout.createSequentialGroup()
*/
                .addContainerGap()
public void setItem(Object item)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
{ this.item = item;
                    .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 278, Short.MAX_VALUE)
}
                    .add(layout.createSequentialGroup()
                        .add(jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 34, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(17, 17, 17)
                        .add(jButton1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jButton5, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE)
                        .add(2, 2, 2)
                        .add(jButton2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jButton3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jButton4, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jButton6, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 23, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(40, 40, 40)
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                            .add(cancelButton)
                            .add(okButton))))
                .addContainerGap())
        );
        pack();
    }// </editor-fold>//GEN-END:initComponents


/**
    private void jButton6MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton6MouseClicked
* Setzt den Nachfolger des Listenelements.
      sortiere();
* @param next    neuer Nachfolger des Listenelements.
      baueTextareaNeuAuf();
*/
    }//GEN-LAST:event_jButton6MouseClicked
public void setNext(ListElement next)
{ this.next = next;
}


/**
    private void jButton5MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton5MouseClicked
* Setzt den Vorgänger des Listenelements.
        liste.toLast();
* @param previous  neuer Vorgänger des Listenelements.
        liste.insertBehind(gibZufallszahl(Integer.parseInt(jTextField1.getText())));
*/
        baueTextareaNeuAuf();
public void setPrevious(ListElement previous)
    }//GEN-LAST:event_jButton5MouseClicked
{ this.previous = previous;
}


}
    private void jButton4MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton4MouseClicked
</source>
        liste.toFirst();
        jTextArea1.setText("");
        rekursiveAusgabe();
    }//GEN-LAST:event_jButton4MouseClicked


==Probleme mit der Implementierung==
    private void jButton3MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton3MouseClicked
* [http://www.u-helmich.de/inf/BlueJ/kurs121/seite15/abi-list.html Hier] sind offene Fragen und Kommentare zusammengefasst.
        liste.toLast();
* [http://informatik.zum.de/pieper/blog/index.php?entry=entry060828-105313 Aufruf zur Diskussion]
        if (!liste.isEmpty()){
            liste.delete();
        }
        baueTextareaNeuAuf();       
    }//GEN-LAST:event_jButton3MouseClicked


==Anwendungsbeispiele==
    private void jButton2MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton2MouseClicked
* [http://informatik.zum.de/pieper/blog/index.php?entry=entry060828-183201 Quiz mit Hilfe einer Liste] + Arbeitsblatt
        liste.toFirst();
* [[Liste mit Zahlen (Informatik)]]
        if (!liste.isEmpty()){
            liste.delete();
        }
        baueTextareaNeuAuf();
    }//GEN-LAST:event_jButton2MouseClicked


==Unterseiten zu List==
    private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton1MouseClicked
{{Kasten blass|
        liste.toLast();
<subpages
        liste.insertBehind(jTextField1.getText());
  parent=Java/List
        baueTextareaNeuAuf();
  order=DESC
    }//GEN-LAST:event_jButton1MouseClicked
  order=lastedit
   
  showpath=no
    private void baueTextareaNeuAuf() {
/>
        if (liste.isEmpty()){
}}
            jTextArea1.setText("Leere Liste\nBitte füge etwas hinzu.");
        }
        else {
            String zwischen="";
            liste.toFirst();
            jTextArea1.setText("Die Liste:\n");
            while (!liste.isBehind()){
              jTextArea1.append(liste.getItem()+"\n");
              liste.next();
            }
        }
    }
   
    private void rekursiveAusgabe() {
        if (liste.isBehind()){
            jTextArea1.append("\nFertig.\n");
        }
        else {
            jTextArea1.append(liste.getItem()+"\n");
            liste.next();
            rekursiveAusgabe();
            jTextArea1.append("*");
        }
    } 
   
    private void sortiere() {
      // Vorstufe von Sortieren durch Einfügen
      // vgl. http://www-i1.informatik.rwth-aachen.de/~algorithmus/algo2.php
      int x,y;
      liste.toFirst();
      liste.next();
      while (!liste.isBehind()){
        x=(Integer) liste.getItem();
        liste.previous();
        y=(Integer) liste.getItem();
        if (x<y) {
            liste.delete();
            liste.insertBehind(y);
        }
        liste.next();
        liste.next();
      } 
    }     
   
    private int gibZufallszahl(int pMaximum) {
        return  (int) ((Math.random()*pMaximum)+1);
    }
   
    private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
        doClose(RET_OK);
    }//GEN-LAST:event_okButtonActionPerformed
   
    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
        doClose(RET_CANCEL);
    }//GEN-LAST:event_cancelButtonActionPerformed
   
    /** Closes the dialog */
    private void closeDialog(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeDialog
        doClose(RET_CANCEL);
    }//GEN-LAST:event_closeDialog
   
    private void doClose(int retStatus) {
        returnStatus = retStatus;
        setVisible(false);
        dispose();
    }
   
    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new GUI(new javax.swing.JFrame(), true).setVisible(true);
            }
        });
    }
   
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton cancelButton;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JButton jButton5;
    private javax.swing.JButton jButton6;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JButton okButton;
    // End of variables declaration//GEN-END:variables
   
    private int returnStatus = RET_CANCEL;
}
</source>


== Siehe auch ==
[[Kategorie:Java]]
* [[Informatik]]
* [[Programmiersprachen]]
* [[Abitur (NRW)]]


== Quellen ==
<references/>
[[Kategorie:Java]]
[[Kategorie:Java]]

Aktuelle Version vom 20. August 2019, 07:50 Uhr

Verkettete Listen gehören zu den dynamischen Datenstrukturen, die eine Speicherung von einer im Vorhinein nicht bestimmten Anzahl von miteinander in Beziehung stehenden Werten einfacher oder zusammengesetzter Datentypen erlauben.

Eine Liste hat ein erstes Element (auch Knoten), dieses wird Kopf genannt. Eine Liste hat auch immer ein letztes Element. Im Gegensatz zum Array muss jedoch nicht festgelegt werden, wie groß die Liste letztlich sein wird. Ein Element einer Liste enthält Daten. Im folgenden Bild sind dies Zahlen. In Java können nicht nur Zahlen in Listen gespeichert werden, beliebige Objekte können in Listen strukturiert werden.

Die Listenart, die uns vornehmlich interessiert, ist eine doppelt verkettete Liste.[1] Das bedeutet,dass von jedem Knoten aus das vorherige und das nachfolgende Element erreicht werden kann.

verkettete Liste


Quiz

Übersicht über die Klasse Quiz

Ein nettes Beispiel für eine Liste ist ein Quiz. Auf Karteikarten stehen je­weils eine Frage und eine Antwort. Die Klasse Quiz legt im Konstruktor 4 Bei­spielfragen an und legt sie als Liste ab (bessere Formulierung?).

Die Methoden der Klasse Quiz verdeutlichen, wie man mit einer Liste umgehen kann. QuizGUI ist eine freiwillige Vertie­fung, auf die nicht näher einge­gangen wird.

Typecast: Object in Karteikarten wandeln

In der Klasse Quiz gibt es folgende Formulierung:

Karteikarte karte = (Karteikarte) liste.getItem();

oder ausführlich:

Karteikarte karte;
karte = (Karteikarte) liste.getItem();

Die Klammern um die Klasse Karteikarte drücken aus, dass der geholte Inhalt der Liste, der grundsätzlich vom Typ Objekt (in Java: Object) ist, in eine Karteikarte umgewandelt wird. Es geschieht ein „Typecasting“ von Object zu Karteikarte.In der Liste lassen sich beliebige Objekte speichern. Das kann String, int, Konto, Karteikarte … sein. Möglich ist auch, dass in einer Liste verschiedene Objekte gespeichert werden (ein Konto und zwei Karteikarten). Allerdings muss man aufgrund dieser Flexibilität selbst dafür sorgen, dass die zurückgegebenen Objekte zu den gewünschten Typen umgewandelt werden, was im obigen Beispiel Karteikarte ist.

Arbeitshinweise
  1. Nennen Sie Methoden, die Sie selbst zum Führen von Listen benötigen würden (z.B. auf einer Adressliste streicheDurch()). Vergleichen Sie Ihre benötigten Methoden mit den Methoden der Klasse „List“, die auf den folgenden Seiten beschrieben werden.
  2. Analysieren Sie das Klassendiagramm und die Beschreibung zu „List“.
    Veranschaulichen Sie die Methoden, indem Sie sich eine Liste als Güterzug vorstellen und den Positionszeiger als Kran, der immer nur auf einen Waggon zugreifen kann.
  3. Analysieren Sie das Quiz-Projekt. Schauen Sie sich zunächst die einfache Klasse Kartei­karte an. Analysieren Sie anschließend die Klasse Quiz.
    Hinweis: werteFragenAus() sorgt dafür, dass Fragen mit falschen Antworten ans Ende der Liste gehängt werden.
  4. Schreiben Sie die Methode steckeAktuelleKarteGanzNachHinten(), die die aktuelle Karte ganz nach hinten schiebt. (analog: nach vorne)
  5. Schreiben Sie die Methode bringeKarteUmEinePositionNachVorne(), die die aktuelle Karte um eins nach vorne schiebt.
  6. Implementieren Sie die folgenden Methoden:
    1. gibRueckwaertsAus(), die ähnlich wie die Ausgabe alle Fragen auf der Konso­le ausgibt, diesmal aber rückwärts (letzte Frage zuerst).
    2. gibLaengeDerListe() , die eine int-Zahl mit der Anzahl der Listenelemente zurückgibt.
    3. geheZuFrageNr(int x), die den Positionszeiger auf die x-te Frage setzt.
  7. Schreiben Sie die Methode sucheFrage(String Antwort), die die Frage zu einer Antwort zurückgibt.

Zuganzeigetafel

Zuganzeigetafel

An Bahnhöfen oder U-Bahn-Stationen gibt es seit einigen Jahren einen besonderen Service: Elektronische Hin­weisschilder zeigen die Züge an, die als nächstes abfahren werden. Dabei wird neben dem Ziel auch das Gleis, die Abfahrtszeit inkl. eventueller Verspätung erfasst. Diese Servicetafeln benötigen folgende Funktionalität:

Es gibt 3 verschiedene Ausgaberoutinen

  1. Alle erfassten Züge müssen angezeigt werden können
  2. Auf spezielle Tafeln können nur die nächsten 10 Züge angezeigt werden.
  3. Alle Züge, die an ein Gleis einfahren (z.B. Gleis 5), können angezeigt werden

Zur Verwaltung gehören die folgenden Routinen:

  1. Die Verspätungszeit und die Gleisnummer können verändert werden
  2. Ein Zug kann komplett gestrichen werden (wenn er abgefahren ist oder ausfällt)
  3. Ein neuer Zug kann eingefügt werden, dabei wird automatisch erkannt, an welche Position ergehört. Fährt er später ab als alle anderen, so wird er ans Ende der Liste gehängt.
    Zusatz:
  4. Ist für ein Gleis die identische Abfahrtszeit angegeben, soll ein Warnhinweis angezeigt werden.
  5. Der nächste Zug, der abfährt, soll bei der Ausgabe mit einem Stern versehen werden.

Arbeitshinweise
  1. Lesen Sie zunächst alleine die Aufgabenbeschreibung und überlegen Sie sich grob eine Realisierung.
  2. Diskutieren Sie in Ihrer Entwicklergruppe, welche Eigenschaften und Methoden die Klasse „Zug“ enthalten muss. Einigen Sie sich auf eine Variante, die dann für alle gilt. Fixieren Sie diese als UML-Diagramm.
  3. Teilen Sie sich die Arbeit auf. Wählen Sie einen Projektkoordinator, der die Übersicht über das Projekt erhält. An seinem Rechner werden die einzelnen Programmteile zu­sammengefügt. Implementieren Sie das Projekt.
Benötigt
  • Liste, while, if...else, boolean, int, double
  • BlueJ, daher ohne main-Methode
Hinweis

Zur Vereinfachung der Aufgabe wird die Zeit als double erfasst. Das kann zu Problemen führen, wenn man Zeiten addieren möchte (z.B. Einrechnen der Verspätung).


Einfügemethode

Die Einfügemethode für einen Zug funktioniert wie folgt: (Der Algorithmus ist nicht unbedingt optimal, aber so ist er noch einfach zu verstehen)


    public void fügeZugHinzu(Zug pZug){
        if (zugliste.isEmpty()) {
            zugliste.insertBehind(pZug);
        }
        else {
            Zug zwischenspeicher;
            zugliste.toFirst();
            boolean schonEingefügt=false;
            while (!zugliste.isBehind() && !schonEingefügt){
                zwischenspeicher = (Zug) zugliste.getItem();
                if (zwischenspeicher.getAbfahrtzeit()>=pZug.getAbfahrtzeit()){
                    zugliste.insertBefore(pZug);
                    schonEingefügt=true;
                }
                zugliste.next();
            }
            if (!schonEingefügt) zugliste.insertBefore(pZug); 
        }
    }

Übung
  1. Weshalb wird zwischenspeicher angelegt? Welche Funktion hat schonEingefügt?
  2. Gliedern Sie den Algorithmus:
    • a) Behandlung einer leeren Liste
    • b) Suchen der Position, an der eingefügt werden soll
    • c) Behandlung am Ende Einfügen
  3. Implementieren Sie als Methode der Verwaltung gibZügeAus(int zahl), die zahl Züge mit einer laufenden Nummer, der Abfahrtszeit, des Ziels und der Gleisnummer ausgibt. Gehen Sie sinnvoll mit dem Problem um, dass zahl größer sein kann als die eingetragenen Züge.
    • Bsp:
    • 1. 14.39 Hamburg Gleis 5
    • 2. 17.29 Bonn Gleis 2
  4. Freiwilliger Zusatz: Schreiben Sie die Methode streicheZugNr (int zahl), die den Listeneintrag Nummer zahl entfernt.


Quelltext

Neben class List sind folgende Klassen erforderlich.

public class Zug {

  // Eigenschaften
  private double abfahrtzeit;
  private double verspätung;
  private int gleisnummer;
  private String zugBezeichnung;
  private String ankunftsBahnhof;
  // Ende Variablen

  public Zug (double pAbfahrtzeit, double pVerspätung, int pGleisnummer, String pZugBezeichnung, String pAnkunftsBahnhof){
    abfahrtzeit= pAbfahrtzeit;
    verspätung = pVerspätung;
    gleisnummer = pGleisnummer;
    zugBezeichnung = pZugBezeichnung;
    ankunftsBahnhof = pAnkunftsBahnhof; 
  }
  
  // Methoden
  public String getAnkunftsBahnhof() {
    return ankunftsBahnhof;
  }

  public void setAnkunftsBahnhof(String ankunftsBahnhof) {
    this.ankunftsBahnhof = ankunftsBahnhof;
  }

  public String getZugBezeichnung() {
    return zugBezeichnung;
  }

  public void setZugBezeichnung(String zugBezeichnung) {
    this.zugBezeichnung = zugBezeichnung;
  }

  public int getGleisnummer() {
    return gleisnummer;
  }

  public void setGleisnummer(int gleisnummer) {
    this.gleisnummer = gleisnummer;
  }

  public double getVerspätung() {
    return verspätung;
  }

  public void setVerspätung(double verspätung) {
    this.verspätung = verspätung;
  }

  public double getAbfahrtzeit() {
    return abfahrtzeit;
  }

  public void setAbfahrtzeit(double abfahrtzeit) {
    this.abfahrtzeit = abfahrtzeit;
  }

  // Ende Ereignisprozeduren
}
public class Verwaltung
{
    private List zugliste;
    
    public Verwaltung()
    {   
        zugliste=new List();
        Zug zug=new Zug(12.05,20,5,"ICE","Lummerland");
        fügeZugHinzu(zug);
        zug=new Zug(11.11,10,2,"RE","Nimmerland");
        fügeZugHinzu(zug);
        zug=new Zug(13.44,20,5,"RB","Sibirien");
        fügeZugHinzu(zug);
        zug=new Zug(12.14,20,5,"RB","Entenhausen");
        fügeZugHinzu(zug);
        zug=new Zug(17.30,20,2,"S-Bahn","Hansaring");
        fügeZugHinzu(zug);        
    }
    
    public void fügeZugHinzu(Zug pZug){
        if (zugliste.isEmpty()) {
            zugliste.insertBehind(pZug);
        }
        else {
            Zug zwischenspeicher;
            zugliste.toFirst();
            boolean schonEingefügt=false;
            while (!zugliste.isBehind() && !schonEingefügt){
                zwischenspeicher = (Zug) zugliste.getItem();
                if (zwischenspeicher.getAbfahrtzeit()>=pZug.getAbfahrtzeit()){
                    zugliste.insertBefore(pZug);
                    schonEingefügt=true;
                }
                zugliste.next();
            }
            if (!schonEingefügt) zugliste.insertBefore(pZug); 
        }
    }
    
}

Implementation der NRW-Zentralabi-Liste

Die Zahlenliste ist wohl eine der einfachsten Anwendungen der Liste. In der Realität kommen Zahlenlisten z.B. bei der Erfassung von Aktienkursen (DAX-Tafel) oder bei der Fieberkurve im Krankenhaus vor. Die folgende Liste basiert verwendet List.


public class ZahlenListe
{
    // Eigenschaften
    private List temperaturListe;

    // Konstruktor
    // Legt eine Liste an und füllt sie mit einigen Beispielwerten.
    public ZahlenListe()
    {
        temperaturListe = new List();
        temperaturListe.insertBehind(2);
        temperaturListe.insertBehind(15);
        temperaturListe.insertBehind(8);
        temperaturListe.insertBehind(4);
        temperaturListe.insertBehind(1);
        temperaturListe.insertBehind(6);
        temperaturListe.insertBehind(5);

    }
    
    public void ausgebenDerListe(){
        temperaturListe.toFirst();
        while (!temperaturListe.isBehind()){
            Integer wert= (Integer) temperaturListe.getItem();
            System.out.println (wert);
            temperaturListe.next();
        }
        System.out.println ("Ende der Liste");
    }
    
    public void neueZahl(int pZahl){
     temperaturListe.toLast();    
     temperaturListe.insertBehind(pZahl);
    }

    public void tauscheErsteBeidenZahlen(){
        temperaturListe.toFirst();
        Integer wert= (Integer) temperaturListe.getItem();
        temperaturListe.next();
        Integer wert2= (Integer) temperaturListe.getItem();
        temperaturListe.update(wert);
        temperaturListe.previous();
        temperaturListe.update(wert2);
    } 
    
    // Ausgeben der höchsten Zahl
    public void gibGrößteZahlAus () {
        temperaturListe.toFirst();
        Integer wert= (Integer) temperaturListe.getItem();
        while (!temperaturListe.isBehind()){
            if (wert<(Integer) temperaturListe.getItem()) {
                wert = (Integer) temperaturListe.getItem();
            }
            temperaturListe.next();
        }
        System.out.println(wert+" ist die größte Zahl");
    }
    
    // Summiere alle Zahlen und gib die Summe zurück
    public int gibSummeZahlZurück () {
        temperaturListe.toFirst();
        int zwischenspeicher;
        zwischenspeicher = 0;
        while (!temperaturListe.isBehind()){
            zwischenspeicher += (Integer) temperaturListe.getItem();
            temperaturListe.next();
        }
        return zwischenspeicher;
    }
    

}


NRW-Zentralabi-Liste mit GUI

  • Der folgende Quelltext verwendet die Klasse List (NRW-Zentralabitur).
  • Die Klasse GUI wurde erstellt mit Netbeans - BlueJ-Edition.

Übung
  • Testen Sie den GUI-Ersteller von Netbeans. Nennen Sie Vor- und Nachteile relativ zur "Handarbeit".
  • Analysieren Sie die Methoden zu den Buttons.
  • Wie oft muss man den "Sortieren-Button" drücken, bis die Liste spätestens sortiert ist? (Wie könnte man das automatisieren?).
  • Beschreiben Sie die Funktionsweise der rekursiven Ausgabe.
  • Fügen Sie einen Button hinzu: größteZahl(), die den größten Listenwert ermittelt und in der Textzeile ausgibt.



ListeGUI.gif


/*
 * GUI.java
 *
 * Created on 20. November 2006, 22:07
 */

/**
 *
 * @author  ugh
 */
public class GUI extends javax.swing.JDialog {
    
    private List liste;
    
    /** A return status code - returned if Cancel button has been pressed */
    public static final int RET_CANCEL = 0;
    /** A return status code - returned if OK button has been pressed */
    public static final int RET_OK = 1;
    
    /** Creates new form GUI */
    public GUI(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
        liste = new List();
        jTextArea1.setText("Leere Liste\nBitte füge etwas hinzu.");
    }
    
    /** @return the return status of this dialog - one of RET_OK or RET_CANCEL */
    public int getReturnStatus() {
        return returnStatus;
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {
        okButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();
        jTextField1 = new javax.swing.JTextField();
        jButton1 = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();
        jButton4 = new javax.swing.JButton();
        jButton5 = new javax.swing.JButton();
        jButton6 = new javax.swing.JButton();

        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                closeDialog(evt);
            }
        });

        okButton.setText("OK");
        okButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                okButtonActionPerformed(evt);
            }
        });

        cancelButton.setText("Cancel");
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        jTextField1.setText("6");

        jButton1.setText("add (am Ende)");
        jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton1MouseClicked(evt);
            }
        });

        jTextArea1.setColumns(20);
        jTextArea1.setRows(5);
        jScrollPane1.setViewportView(jTextArea1);

        jButton2.setText("remove (Anfang)");
        jButton2.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton2MouseClicked(evt);
            }
        });

        jButton3.setText("remove (Ende)");
        jButton3.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton3MouseClicked(evt);
            }
        });

        jButton4.setText("rekursive Ausgabe");
        jButton4.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton4MouseClicked(evt);
            }
        });

        jButton5.setText("add Zufallszahl");
        jButton5.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton5MouseClicked(evt);
            }
        });

        jButton6.setText("sortiere");
        jButton6.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton6MouseClicked(evt);
            }
        });

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 234, Short.MAX_VALUE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jButton6, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE)
                    .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                        .add(layout.createSequentialGroup()
                            .add(okButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 67, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                            .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                            .add(cancelButton))
                        .add(jTextField1))
                    .add(jButton4, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE)
                    .add(jButton3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE)
                    .add(jButton2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE)
                    .add(jButton5, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE)
                    .add(jButton1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE))
                .addContainerGap())
        );

        layout.linkSize(new java.awt.Component[] {cancelButton, okButton}, org.jdesktop.layout.GroupLayout.HORIZONTAL);

        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 278, Short.MAX_VALUE)
                    .add(layout.createSequentialGroup()
                        .add(jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 34, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(17, 17, 17)
                        .add(jButton1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jButton5, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE)
                        .add(2, 2, 2)
                        .add(jButton2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jButton3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jButton4, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jButton6, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 23, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(40, 40, 40)
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                            .add(cancelButton)
                            .add(okButton))))
                .addContainerGap())
        );
        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButton6MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton6MouseClicked
       sortiere();
       baueTextareaNeuAuf();
    }//GEN-LAST:event_jButton6MouseClicked

    private void jButton5MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton5MouseClicked
        liste.toLast();
        liste.insertBehind(gibZufallszahl(Integer.parseInt(jTextField1.getText())));
        baueTextareaNeuAuf();
    }//GEN-LAST:event_jButton5MouseClicked

    private void jButton4MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton4MouseClicked
        liste.toFirst();
        jTextArea1.setText("");
        rekursiveAusgabe();
    }//GEN-LAST:event_jButton4MouseClicked

    private void jButton3MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton3MouseClicked
        liste.toLast();
        if (!liste.isEmpty()){
            liste.delete();
        }
        baueTextareaNeuAuf();        
    }//GEN-LAST:event_jButton3MouseClicked

    private void jButton2MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton2MouseClicked
        liste.toFirst();
        if (!liste.isEmpty()){
            liste.delete();
        }
        baueTextareaNeuAuf();
    }//GEN-LAST:event_jButton2MouseClicked

    private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton1MouseClicked
        liste.toLast();
        liste.insertBehind(jTextField1.getText());
        baueTextareaNeuAuf();
    }//GEN-LAST:event_jButton1MouseClicked
    
    private void baueTextareaNeuAuf() {
        if (liste.isEmpty()){
            jTextArea1.setText("Leere Liste\nBitte füge etwas hinzu.");
        }
        else {
            String zwischen="";
            liste.toFirst(); 
            jTextArea1.setText("Die Liste:\n");
            while (!liste.isBehind()){
               jTextArea1.append(liste.getItem()+"\n"); 
               liste.next();
            }
        }
    }
    
    private void rekursiveAusgabe() {
        if (liste.isBehind()){
            jTextArea1.append("\nFertig.\n");
        }
        else {
            jTextArea1.append(liste.getItem()+"\n"); 
            liste.next();
            rekursiveAusgabe();
            jTextArea1.append("*");
        }
    }  
    
    private void sortiere() {
      // Vorstufe von Sortieren durch Einfügen
      // vgl. http://www-i1.informatik.rwth-aachen.de/~algorithmus/algo2.php
      int x,y;
      liste.toFirst();
      liste.next();
      while (!liste.isBehind()){
         x=(Integer) liste.getItem();
         liste.previous();
         y=(Integer) liste.getItem();
         if (x<y) {
            liste.delete();
            liste.insertBehind(y);
         }
         liste.next();
         liste.next();
      }  
    }      
    
    private int gibZufallszahl(int pMaximum) {
        return  (int) ((Math.random()*pMaximum)+1);
    }
    
    private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
        doClose(RET_OK);
    }//GEN-LAST:event_okButtonActionPerformed
    
    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
        doClose(RET_CANCEL);
    }//GEN-LAST:event_cancelButtonActionPerformed
    
    /** Closes the dialog */
    private void closeDialog(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeDialog
        doClose(RET_CANCEL);
    }//GEN-LAST:event_closeDialog
    
    private void doClose(int retStatus) {
        returnStatus = retStatus;
        setVisible(false);
        dispose();
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new GUI(new javax.swing.JFrame(), true).setVisible(true);
            }
        });
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton cancelButton;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JButton jButton5;
    private javax.swing.JButton jButton6;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JButton okButton;
    // End of variables declaration//GEN-END:variables
    
    private int returnStatus = RET_CANCEL;
}

Quellen

  1. Die Zentralabikonforme Liste ist doppelt verknüpft, das sie den Nachfolger und auch den Vorgänger kennt.