Java/List: Unterschied zwischen den Versionen

Aus ZUM-Unterrichten
main>Ugh
(→‎Siehe auch: Abitur (NRW))
(akt - Unterseiten in Lernpfad integriert)
Markierung: 2017-Quelltext-Bearbeitung
 
(22 dazwischenliegende Versionen von 6 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
==Erster Implementierungsansatz==
{{DISPLAYTITLE:(verkettete) Listen}}''
* ??? Wahrscheinlich ist das Positionszähler nicht so gemeint. Er soll anscheinend selbst ein Listenelement sein. Besitzt jemand einen stimmige Quelltext?
'''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.


===Mögliche Interpretation===
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.  
Realisiert mit ArrayList:
<java>
import java.util.ArrayList;


public class List {
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.
private ArrayList liste;
private int positionszeiger;


public List(){
[[Datei:Java-Liste-1.png|thumb|600px|left|verkettete Liste]]
  liste = new ArrayList(); // die Liste ist leer
{{clear}}
  positionszeiger=-1; // der Positionszeiger steht vor der Liste
== Quiz ==
  insertBehind("Element a");
[[Datei:Java-Liste-Quiz.png|thumb|Übersicht über die Klasse Quiz]]
  insertBehind("Element b");
Ein nettes Beispiel für eine Liste ist ein Quiz. Auf Karteikarten stehen je­weils eine Frage und eine Antwort.
  insertBehind("Element c");
Die Klasse Quiz legt im Konstruktor 4 Bei­spielfragen an und legt sie als Liste ab  (<span style="color:red">bessere Formulierung?</span>).
  insertBehind("Element d");
 
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 &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.
 
{{Box|Arbeitshinweise|
# 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}}
 
== Zuganzeigetafel ==
[[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
 
Zur Verwaltung gehören die folgenden Routinen:
# 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.
 
{{Box|Arbeitshinweise|# Lesen Sie zunächst alleine die Aufgabenbeschreibung und überlegen Sie sich grob eine Realisierung.
# 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}}
 
;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)
 
 
<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>
 
{{Übung|
# Weshalb wird <code>zwischenspeicher</code> angelegt? Welche Funktion hat <code>schonEingefügt</code>?
# 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.
}}
 
=== Quelltext  ===
Neben [[Java/List|class List]] sind folgende Klassen erforderlich.
 
<source lang="java">
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
}
}
</source>


public void insertBefore (Object pObject){   
<source lang="java">
  liste.add(positionszeiger, pObject);
public class Verwaltung
  positionszeiger--;
{
    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);  
        }
    }
   
}
}
</source>
== 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 [[Java/List|List]].
<source lang="java">
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;
    }
   


public void insertBehind (Object pObject){ 
  liste.add(positionszeiger+1, pObject);
}
}
</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|
* 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: <code>größteZahl()</code>, die den größten Listenwert ermittelt und in der Textzeile ausgibt.
}}
[[Bild:ListeGUI.gif]]
<source lang="java">
/*
* 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);
            }
        });


public void update (Object pObject){  
        jButton3.setText("remove (Ende)");
  liste.set(positionszeiger, pObject);
        jButton3.addMouseListener(new java.awt.event.MouseAdapter() {
}
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton3MouseClicked(evt);
            }
        });


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


public void next(){
        jButton5.setText("add Zufallszahl");
  if (positionszeiger!=liste.size()) positionszeiger++;
        jButton5.addMouseListener(new java.awt.event.MouseAdapter() {
}
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton5MouseClicked(evt);
            }
        });


public void previous(){
        jButton6.setText("sortiere");
  if (positionszeiger>-1) positionszeiger--;
        jButton6.addMouseListener(new java.awt.event.MouseAdapter() {
}
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton6MouseClicked(evt);
            }
        });


public void toFirst(){
        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
  positionszeiger=0;
        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())
        );


public void toLast(){
        layout.linkSize(new java.awt.Component[] {cancelButton, okButton}, org.jdesktop.layout.GroupLayout.HORIZONTAL);
  positionszeiger=liste.size()-1;
}


public Object getItem(){
        layout.setVerticalGroup(
  if (liste.size()==0 || positionszeiger==-1 || positionszeiger>=liste.size())
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
    return null;
            .add(layout.createSequentialGroup()
  else return liste.get(positionszeiger);
                .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


public boolean isEmpty (){  
    private void jButton4MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton4MouseClicked
  return (liste.size()==0);
        liste.toFirst();
}
        jTextArea1.setText("");
        rekursiveAusgabe();
    }//GEN-LAST:event_jButton4MouseClicked


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


public boolean isBehind (){  
    private void jButton2MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton2MouseClicked
  return (positionszeiger>=liste.size());
        liste.toFirst();
}
        if (!liste.isEmpty()){
            liste.delete();
        }
        baueTextareaNeuAuf();
    }//GEN-LAST:event_jButton2MouseClicked


// nicht in den Vorgaben vorgesehener Zusatz
    private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton1MouseClicked
public void gibAufKonsoleAus(){
        liste.toLast();
  if (liste.size()==0) System.out.println("Leere Liste");
        liste.insertBehind(jTextField1.getText());
  else {
        baueTextareaNeuAuf();
      System.out.println("\n*** Liste ***");
    }//GEN-LAST:event_jButton1MouseClicked
      if (positionszeiger==-1) System.out.println("> -1");
   
      for (int i=0; i<liste.size();i++){
    private void baueTextareaNeuAuf() {
          if (i==positionszeiger) System.out.print("> "+i+":");
        if (liste.isEmpty()){
          else System.out.print("  "+i+":");
            jTextArea1.setText("Leere Liste\nBitte füge etwas hinzu.");
          System.out.println ((String) liste.get(i));
        }
      }
        else {
      if (positionszeiger>=liste.size()) System.out.print("> "+positionszeiger);
            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>


}
[[Kategorie:Java]]
</java>
 
==Probleme mit der Implementierung==
* [http://www.u-helmich.de/inf/BlueJ/kurs121/seite15/abi-list.html Hier] sind offene Fragen und Kommentare zusammengefasst.
* [http://informatik.zum.de/pieper/blog/index.php?entry=entry060828-105313 Aufruf zur Diskussion]
 
==Anwendungsbeispiele==
* [http://informatik.zum.de/pieper/blog/index.php?entry=entry060828-183201 Quiz mit Hilfe einer Liste] + Arbeitsblatt


== Siehe auch ==
== Quellen ==
* [[Informatik]]
<references/>
* [[Programmiersprachen]]
[[Kategorie:Java]]
* [[Abitur (NRW)]]
[[Kategorie:Informatik]]

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.