public class List{
private List first;
private List last;
private List current;
private List next;
private List previous;
private Object content;
public List(){
first.next = last; --> hier ist das Problem; es wird immer eine Nullpointerexception geworfen, wie kann ich
last.previous = first; vermeiden???
current = first;
}
...
aber vorsichtig mit dieser Initialisierung,
so im Konstruktor wäre das bös:
Liste A erstellt eine Exemplarvariable A.first
Liste A.first erstellt eine Exemplarvariable A.first.first
Liste A.first.first erstellt eine Exemplarvariable A.first.first.first
....
Was soll denn erstellt werden, wenn du
List list =new List();
aufrufst?
Ich würde erwarten, dass
list.first dann erstmal 'null' ist.
Vielleicht ist sowas wie
Code:
public List(){
first = this;
last = this;
first.next = last;
last.previous = first;
current = first;
}
ein möglicher Ansatz?
Üblicherweise werden solche Datentypen streng algebraisch spezifiziert (ja, "Algebra" ist das Zeuch aus Mathe). Wenn man weiß, wie sich die Klasse verhalten soll, kann man sie auch schreiben. Ansonsten - schreibt man "irgendwas".
Dokumentation der Methoden der Klasse List Konstruktor List() Nachher Eine leere Liste ist angelegt. Der interne Positionszeiger steht vor der leeren Liste.
Anfrage isEmpty(): boolean
Nachher
Die Anfrage liefert den Wert true, wenn die Liste keine Elemente enthält,
sonst liefert sie den Wert false.
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 fal-
se.
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.
Auftrag next()
Nachher
Der Positionszeiger ist um eine Position in Richtung Listenende weiterger
ü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.
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.
Auftrag toFirst()
Nachher
Der Positionszeiger steht auf dem ersten Listenelement. Falls die Liste leer
ist befindet er sich jetzt hinter der Liste.
Auftrag toLast()
Nachher
Der Positionszeiger steht auf dem letzten Listenelement. Falls die Liste leer
ist befindet er sich jetzt vor der Liste.
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.
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.
ich will ja eine verkettete liste programmieren nach dieser dokumentation.
das problem ist, das diese liste als elemente Objekte von der Klasse liste enthalten soll.
ich habe eigentlich alle methoden programmiert, und habe auch ein testprogramm geschrieben, wobei schon bei dem konstruktior nullpointerexception geworfen wird
Code:
import java.util.NoSuchElementException;
public class List{
private List first;
private List last;
private List current;
private List next;
private List previous;
private Object content;
public List(){
first.next = last;
last.previous = first;
current = first;
}
public boolean isEmpty(){
if(first.next == last){
return true;
}
else{
return false;
}
}
public boolean isBefore(){
if(current == first){
return true;
}
else{
return false;
}
}
public boolean isBehind(){
if(current == last){
return true;
}
else{
return false;
}
}
public void next(){
if(!this.isBehind()){
if(this.isBefore()){
current = first.next;
}
else{
current = current.next;
}
}
}
public void previous(){
if(!this.isBefore()){
if(this.isBehind()){
current = last.previous;
}
else{
current = current.previous;
}
}
}
public void toFirst(){
if(!this.isEmpty()){
current = first.next;
}
else {
current = last;
}
}
public Object getItem(){
if(!this.isEmpty()){
Object cur = current.content;
return cur;
}
else{
return null;
}
}
public void update(Object obj){
if(!this.isEmpty()){
if(this.isBefore() || this.isBehind()){
throw new NoSuchElementException("update ausserhalb!!!");
}
else{
List help = new List();
help.content = obj;
help.previous = current.previous;
help.next = current.next;
current = help;
}
}
else{
throw new NoSuchElementException("Liste leer!!!");
}
}
public void insertBefore(Object obj){
if(!this.isBefore()){
List help = new List();
help.content = obj;
help.previous = current.previous;
current.previous = help;
help.next = current;
}
else{
throw new NoSuchElementException("insert before!!!");
}
}
public void insertBehind(Object obj){
if(!this.isBehind()){
List help = new List();
help.content = obj;
help.next = current.next;
current.next.previous = help;
current.next = help;
help.previous = current;
}
else{
throw new NoSuchElementException("insert behind!!!");
}
}
public void delete(){
if(this.isBefore() || this.isBehind()){
throw new NoSuchElementException("delete ausserhalb!!!");
}
else{
current.previous.next = current.next;
current.next.previous = current.previous;
}
}
public void toLast() {
if(!this.isEmpty()){
current = last.previous;
}
else{
current = first;
}
}
}
first.next = last;
wobei first null ist, also da ist die Exception doch klar
verwende zunächst diesen Konstruktor:
public List(){
}
falls irgendwann mal was im Konstruktor getan werden muss,
dann kannst du es immer noch einfügen,
im Moment sehe ich keinen Anlass dazu, oder warum willst du da irgendwas setzen?
dass die Liste selber wieder Listen enthält ist durchaus machbar,
du darfst nur nicht im Konstruktor Listen erzeugen, das gibt eine Endlosschleife
Also, der Beschreibung nach würde ich im Default-Konstruktor erstmal alles auf 'null' setzen - höchstens noch ein
current = this;
rein. Evtl. musst du dann aber einige andere Methoden ein bißchen ändern.
wenn das eine verkettete liste werden soll ist ein:
public class List{
private List first;
private List last;
private List current;
private List next;
private List previous;
einfach sinnlos, und was wird dir auch auffallen, wenn du dein script nochmal aufmerksam durchliets und/oder drüber nachdenkst was da in deiner klasse steht
noch was allgemeines:
es ist schlecht, die Verknüpfungen der Liste in den enthaltenen Objekten zu speichern (next, previous)
stell dir vor, du möchtest ein Objekt in zwei verschiedenen Listen an unterschiedlichen Positionen speichern,
beim Einfügen in die zweite Liste entfernst du das Objekt aus der ersten oder schlimmer noch:
einer der beiden Links (next, previous) zeigt auf ein Element der ersten Liste, der andere auf die zweite Liste,
deshalb verwendet man normalerweise Entry-Objekte, die pro Liste eindeutig sind und die Verknüpfung regeln,
nach außen sind diese nicht sichtbar,
die eigentlichen Elemente sind dann einfach in einem Entry abgelegt und müssen keine Vernüpfungs-Links enthalten
edit:
lange Rede und dann sehe ich dass du das ja schon so machst:
List help = new List();
help.content = obj;
dann ist es aber merkwürdig, das du für die Liste selber sowie die einzelnen Listenglieder die gleiche Klasse nimmst..,
(oder ist das vorgegeben?, ich lese mal lieber nicht die Aufgabenstellung weiter )