Java/List: Unterschied zwischen den Versionen

Aus ZUM-Unterrichten
main>Ugh
main>DiNaro
Zeile 72: Zeile 72:
;Korrekturen:
;Korrekturen:
11.09. - insertBehind: Positionszeiger wird vor und zurück gestellt
11.09. - insertBehind: Positionszeiger wird vor und zurück gestellt
http://informatik.zum.de/pieper/blog/index.php?entry=entry060828-105313
==Zweiter Implementierungsansatz OOP pur==
* ??? Warscheinlich 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.
<java>
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
* <b>Bestandteil des Zentralabiturs 2009</b><br>
* <br>
* Objekte der Klasse List verwalten beliebige Objekte nach einem Listenprinzip. Ein
* interner Positionszeiger wird durch die Listenstruktur bewegt, seine Position markiert
* ein aktuelles Objekt. Die Lage des Positionszeigers kann abgefragt, verändert und die
* Objektinhalte an den Positionen können gelesen oder verändert werden. Die Klasse Stack
* 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>
* <b> Nicht Bestandteil des Zentralabiturs 2009</b> - 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;
/**
* Attribut der Positionszeiger befindet sich hinter der Liste (Flag).
*/
private boolean behind;
/**
* Attribut aktuelles Element.
*/
private ListElement current;
/**
* Attribut erstes Element der Liste
*/
private ListElement first;
/**
* Attribut letztes Element der Liste.
*/
private ListElement last;
/**
* Der Konstruktor erzeugt eine leere lineare Liste.<br>
* <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;
}
/**
* Kopiert die Liste - <b>Nicht Bestandteil des Zentralbiturs 2009!!!</b><br>
* ("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());
}
}
/**
* Löscht des aktuellen Listenelement.<br>
* <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;
}
}
/**
* Gibt den Inhalt des aktuellen Listenelementes zurück, ohne die Liste zu verändern.<br>
* <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;
}
}
/**
* Einfügen eines Listenelementes vor das aktuelle.<br>
* <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
}
}
}
}
/**
* Einfügen eines Listenlementes hinter das aktuelle.<br>
* <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
}
}
}
}
/**
* Steht der Positionszeiger vor der Liste?<br>
* <br>
*
* <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;
}
/**
* Steht der Positionszeiger hinter der Liste?<br>
* <br>
*
* <pre>
* Anfrage      isBehind(): boolean
* Nachher      Die Anfrage liefert den Wert true, wenn der Positionszeiger hinter dem
*              letzten Listenelement oder hinter der leeren Liste steht, sonst liefert
*              sie den Wert false.
* </pre>
*
* @return liefert den Wert true, wenn der Positionszeiger hinter dem letzten
*        Listenelement oder hinter der leeren Liste steht, sonst liefert sie den Wert
*        false.
*/
public boolean isBehind()
{
return this.behind;
}
/**
* Enthält die Liste keine Elemente?<br>
* <br>
*
* <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
}
}
/**
* Setze das aktuelle Listenelement auf das vorherige.<br>
* <br>
*
* <pre>
* Auftrag      previous()
* Nachher      Der Positionszeiger ist um eine Position in Richtung Listenanfang
*              weitergerückt, d.h. wenn er hinter der Liste stand, wird das Element am
*              Listenende zum aktuellen Element, ansonsten das jeweils vorhergehende
*              Listenelement. Stand der Positionszeiger auf dem ersten Listenelement,
*              befindet er sich jetzt vor der Liste. Befand er sich vor der Liste, hat
*              er sich nicht verändert.
* </pre>
*/
public void previous()
{
if (!this.isEmpty())
{ /// Der Positionszeiger bleibt unverändert, wenn die Liste leer ist
if (this.behind)
{ // Der Positionszeiger steht hinter der Liste; das letzte Element wird aktuelles
this.current = this.last;
this.behind = false;
}
else
{// Der Positionszeiger steht nicht hinter der Liste
if (this.current != null)
{ // das jeweils vorhergehende Listenelement wird aktuelles
this.current = this.current.getPrevious();
if (this.current == null)
{ // Der Positionszeiger zeigt vor das erste Element
this.before = true;
}
}
} // Der Positionszeiger befindet sich vor der Liste und bleibt unverändert
}
}
/**
* Speichert die gesamte Liste als Objekt in einer Datei - <b>Nicht Bestandteil des
* Zentralbiturs 2009!!!</b><br>
* Das aktuelles Element bleibt erhalten!
*
* @param fileName [Laufwerk][Pfad]Dateiname.
* @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();
}
/**
* 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);
}
}
}
////////////////////////////////// Basisklasse ListElement /////////////////////////////////
import java.io.Serializable;
/**
* Datei ListElement.java (Klasse Listelement mit generalisiertem Datentyp Object).<br>
* <br>
* Die Klasse ListElement ist die <b>Basisklasse für doppelt verkette Listen</b>.<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>
* <b>Die Klasse ist nicht Bestandteil des Zentralabiturs 2009, aber notwendig!!!</b>
*
* @author <a href="mailto:schule@dinro.de">DiNaro</a>
* @version 1.0z+ 2006-09-11
*/
public class ListElement implements Serializable
{
/**
* Attribut dient zur Serialisierung.
*/
private static final long serialVersionUID = 8626283657638014888L;
/**
* Attribut Date des Listenelements.
*/
private Object item;
/**
* Attribut Nachfolger des Listenelements.
*/
private ListElement next;
/**
* Attribut Vorgänger des Listenelements.
*/
private ListElement previous;
/**
* Der Konstruktor erzeugt ein Listenelement mit Date, Vorgänger und Nachfolger.
*
* @param item Date des Listenelements.
* @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;
}
/**
* Gibt die Date des Elements zurück.
* @return  Date des Listenelements.
*/
public Object getItem()
{ return this.item;
}
/**
* Gibt den Nachfolger des Listenelements zurück.
* @return    Nachfolger des Listenelements.
*/
public ListElement getNext()
{ return this.next;
}
/**
* Gibt den Vorgänger des Listenelements zurück.
* @return  Vorgänger des Listenelements.
*/
public ListElement getPrevious()
{ return this.previous;
}
/**
* Setzt die Date des Listenelements.
* @param item    neue Date des Listenelements.
*/
public void setItem(Object item)
{ this.item = item;
}
/**
* Setzt den Nachfolger des Listenelements.
* @param next    neuer Nachfolger des Listenelements.
*/
public void setNext(ListElement next)
{ this.next = next;
}
/**
* Setzt den Vorgänger des Listenelements.
* @param previous  neuer Vorgänger des Listenelements.
*/
public void setPrevious(ListElement previous)
{ this.previous = previous;
}
}
</java>


==Probleme mit der Implementierung==
==Probleme mit der Implementierung==

Version vom 12. September 2006, 15:37 Uhr

Erster Implementierungsansatz

  • ??? Wahrscheinlich ist das Positionszähler nicht so gemeint. Er soll anscheinend selbst ein Listenelement sein. Besitzt jemand einen stimmige Quelltext?

Mögliche Interpretation

Realisiert mit ArrayList: <java> import java.util.ArrayList;

public class List { private ArrayList liste; private int positionszeiger;

public List(){

  liste = new ArrayList(); // die Liste ist leer
  positionszeiger=-1; // der Positionszeiger steht vor der Liste

}

public void insertBefore (Object pObject){

  liste.add(positionszeiger, pObject);
  positionszeiger--;

}

public void insertBehind (Object pObject){

  liste.add(positionszeiger+1, pObject);

}

public void update (Object pObject){

  liste.set(positionszeiger, pObject);

}

public void delete (){

  liste.remove(positionszeiger);

}

public void next(){

  if (positionszeiger!=liste.size()) positionszeiger++;

}

public void previous(){

  if (positionszeiger>-1) positionszeiger--;

}

public void toFirst(){

  positionszeiger=0;

}

public void toLast(){

  positionszeiger=liste.size()-1;

}

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 (){

  return (positionszeiger<0);

}

public boolean isBehind (){

  return (positionszeiger>=liste.size());

}

} </java>

Korrekturen

11.09. - insertBehind: Positionszeiger wird vor und zurück gestellt http://informatik.zum.de/pieper/blog/index.php?entry=entry060828-105313

Zweiter Implementierungsansatz OOP pur

  • ??? Warscheinlich 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.

<java> import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable;

/**

* Bestandteil des Zentralabiturs 2009
*
* Objekte der Klasse List verwalten beliebige Objekte nach einem Listenprinzip. Ein * interner Positionszeiger wird durch die Listenstruktur bewegt, seine Position markiert * ein aktuelles Objekt. Die Lage des Positionszeigers kann abgefragt, verändert und die * Objektinhalte an den Positionen können gelesen oder verändert werden. Die Klasse Stack * stellt Methoden in folgender Syntax zur Verfügung:

*

    *
  • public List()
  • *
  • public boolean isEmpty()
  • *
  • public boolean isBefore()
  • *
  • public boolean isBehind()
  • *
  • public void next()
  • *
  • public void previous()
  • *
  • public void toFirst()
  • *
  • public void toLast()
  • *
  • public Object getItem()
  • *
  • public void update (Object pObject)
  • *
  • public void insertBefore (Object pObject)
  • *
  • public void insertBehind (Object pObject)
  • *
  • public void delete()
  • *
*  Nicht Bestandteil des Zentralabiturs 2009 - dient der praktischen Anwendung

*

    *
  • public clone()
  • *
  • public load(String fileName)
  • *
  • public save(String fileName)
  • *
*
* @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;

/** * Attribut der Positionszeiger befindet sich hinter der Liste (Flag). */ private boolean behind;

/** * Attribut aktuelles Element. */ private ListElement current;

/** * Attribut erstes Element der Liste */ private ListElement first;

/** * Attribut letztes Element der Liste. */ private ListElement last;

/** * Der Konstruktor erzeugt eine leere lineare Liste.
*
*

*

	 * Konstruktor   List()
	 * <br>
	 * Nachher       Eine leere Liste ist angelegt.
	 *               Der interne Positionszeiger steht vor der leeren Liste.
	 * 

*/ public List() { this.first = null; this.last = null; this.current = null; this.before = true; this.behind = false; }

/** * Kopiert die Liste - Nicht Bestandteil des Zentralbiturs 2009!!!
* ("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()); } }

/** * Löscht des aktuellen Listenelement.
*
*

*

	 * 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.
	 * 

*/ 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; } }

/** * Gibt den Inhalt des aktuellen Listenelementes zurück, ohne die Liste zu verändern.
*
*

*

	 * 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.
	 * 

* * @return item Inhalt des aktuellen Listenelementes. */ public Object getItem() { if (this.current != null) { return this.current.getItem(); } else { return null; } }

/** * Einfügen eines Listenelementes vor das aktuelle.
*
*

*

	 * 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.
	 * 

* * @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 } } } }

/** * Einfügen eines Listenlementes hinter das aktuelle.
*
*

*

	 * 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.
	 * 

* * @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 } } } }

/** * Steht der Positionszeiger vor der Liste?
*
*

*

	 * 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.
	 * 

* * @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; }

/** * Steht der Positionszeiger hinter der Liste?
*
*

*

	 * Anfrage       isBehind(): boolean
	 * Nachher       Die Anfrage liefert den Wert true, wenn der Positionszeiger hinter dem
	 *               letzten Listenelement oder hinter der leeren Liste steht, sonst liefert
	 *               sie den Wert false.
	 * 

* * @return liefert den Wert true, wenn der Positionszeiger hinter dem letzten * Listenelement oder hinter der leeren Liste steht, sonst liefert sie den Wert * false. */ public boolean isBehind() { return this.behind; }

/** * Enthält die Liste keine Elemente?
*
*

*

	 * Anfrage       isEmpty(): boolean
	 * Nachher       Die Anfrage liefert den Wert true, wenn die Liste keine Elemente
	 *               enthält, sonst liefert sie den Wert false.
	 * 

* * @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 - Nicht Bestandteil des * Zentralbiturs 2009!!!
* 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.
*
*

*

	 * 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.
	 * 

*/ 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 } }

/** * Setze das aktuelle Listenelement auf das vorherige.
*
*

*

	 * Auftrag       previous()
	 * Nachher       Der Positionszeiger ist um eine Position in Richtung Listenanfang
	 *               weitergerückt, d.h. wenn er hinter der Liste stand, wird das Element am
	 *               Listenende zum aktuellen Element, ansonsten das jeweils vorhergehende
	 *               Listenelement. Stand der Positionszeiger auf dem ersten Listenelement,
	 *               befindet er sich jetzt vor der Liste. Befand er sich vor der Liste, hat
	 *               er sich nicht verändert.
	 * 

*/ public void previous() { if (!this.isEmpty()) { /// Der Positionszeiger bleibt unverändert, wenn die Liste leer ist if (this.behind) { // Der Positionszeiger steht hinter der Liste; das letzte Element wird aktuelles this.current = this.last; this.behind = false; } else {// Der Positionszeiger steht nicht hinter der Liste if (this.current != null) { // das jeweils vorhergehende Listenelement wird aktuelles this.current = this.current.getPrevious(); if (this.current == null) { // Der Positionszeiger zeigt vor das erste Element this.before = true; } } } // Der Positionszeiger befindet sich vor der Liste und bleibt unverändert } }

/** * Speichert die gesamte Liste als Objekt in einer Datei - Nicht Bestandteil des * Zentralbiturs 2009!!!
* Das aktuelles Element bleibt erhalten! * * @param fileName [Laufwerk][Pfad]Dateiname. * @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.
*
*

*

	 * Auftrag       toFirst()
	 * Nachher       Der Positionszeiger steht auf dem ersten Listenelement.
	 *               Falls die Liste leer ist befindet er sich jetzt hinter der Liste.
	 * 

*/ public void toFirst() { this.current = this.first; this.before = false; this.behind = this.isEmpty(); }

/** * Setzt das aktuelle Listenelement auf das letzte zurück.
*
*

*

	 * Auftrag       toLast()
	 * Nachher       Der Positionszeiger steht auf dem letzten Listenelement.
	 *               Falls die Liste leer ist befindet er sich jetzt vor der Liste.
	 * 

*/ public void toLast() { this.current = this.last; this.behind = false; this.before = this.isEmpty(); }

/**

*

	 * 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.
	 * 

* * @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); } }

} ////////////////////////////////// Basisklasse ListElement ///////////////////////////////// import java.io.Serializable;

/**

* Datei ListElement.java (Klasse Listelement mit generalisiertem Datentyp Object).
*
* Die Klasse ListElement ist die Basisklasse für doppelt verkette Listen.
*
* Ein ListElement enthält eine Date, einen Verweis auf den Vorgänger und einen Verweis * auf den Nachfolger.
* * Die Klasse ist wegen der Speicherbarkeit der Oberklasse serialisiert.
* 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 { /** * Attribut dient zur Serialisierung. */ private static final long serialVersionUID = 8626283657638014888L;

/** * Attribut Date des Listenelements. */ private Object item;

/** * Attribut Nachfolger des Listenelements. */ private ListElement next;

/** * Attribut Vorgänger des Listenelements. */ private ListElement previous;

/** * Der Konstruktor erzeugt ein Listenelement mit Date, Vorgänger und Nachfolger. * * @param item Date des Listenelements. * @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; }

/** * Gibt die Date des Elements zurück. * @return Date des Listenelements. */ public Object getItem() { return this.item; }

/** * Gibt den Nachfolger des Listenelements zurück. * @return Nachfolger des Listenelements. */ public ListElement getNext() { return this.next; }

/** * Gibt den Vorgänger des Listenelements zurück. * @return Vorgänger des Listenelements. */ public ListElement getPrevious() { return this.previous; }

/** * Setzt die Date des Listenelements. * @param item neue Date des Listenelements. */ public void setItem(Object item) { this.item = item; }

/** * Setzt den Nachfolger des Listenelements. * @param next neuer Nachfolger des Listenelements. */ public void setNext(ListElement next) { this.next = next; }

/** * Setzt den Vorgänger des Listenelements. * @param previous neuer Vorgänger des Listenelements. */ public void setPrevious(ListElement previous) { this.previous = previous; }

} </java>

Probleme mit der Implementierung

Anwendungsbeispiele

Siehe auch