Erklaerung Listen

Diskutiere Erklaerung Listen im Java Basics - Anfänger-Themen Bereich.
Bitte aktiviere JavaScript!
S

Saylles

Hallo kann mir wer was empfehlen zum Thema listen.
Ich rede jetzt nicht von Linklist aus Java.util sondern selber welche schreiben ohne die lib.

Ich habe selber eine geschrieben bekommen, die sich rekursiv selber aufruft und bei jedem Schleifendurchlauf das ende neu bestimmt. Jetzt bekomme ich es einfach nicht hin das ende in einer var zu speichern um das , dass ende nicht immer neu gefunden werden muss.
 
Tarrew

Tarrew

Zeig uns doch mal deinen Code, dann kann man dir auf der Basis helfen.
 
S

Saylles

Java:
class Listenelement {
    String daten;
    Listenelement naechster, ende;

    void setDaten(String datenneu) {
        daten = datenneu;
        naechster = null;
        ende = naechster;
    }

    void anhaengen(String datenneu) {
        if (naechster == null ) {
            naechster = new Listenelement();
            naechster.setDaten(datenneu);
        } else
            naechster.anhaengen(datenneu)
            ;
        System.out.println("Daten " + datenneu + " wurden eingefuegt.");
        
        
    }
        
    
    
    

    void ausgeben() {
        System.out.println(daten);
        System.out.println();
        if (naechster != null)
            naechster.ausgeben();
    }

}

public class Listev2 {
    
    
    
    

    public static void main(String[] args) {
        
        Listenelement listenAnfang = new Listenelement();
        
        Listenelement listenEnde = new Listenelement();
        
        listenAnfang.setDaten("Element 1");

        for (int element = 2 ; element < 4 ; element++)
            listenAnfang.anhaengen("Element " + element);
        
            listenAnfang.ausgeben();
    }
    

}
 
Tarrew

Tarrew

Du willst also beim anhängen nicht jedes Mal das Ende suchen? Wenn man bei deiner Struktur bleiben möchte, könnte man das wohl so machen:
Java:
class Listenelement {
    String daten;
    Listenelement naechster, ende;

    void setDaten(String datenneu) {
        daten = datenneu;
        ende = this;
    }

    void anhaengen(String datenneu) {
        Listenelement neu = new Listenelement();
        neu.setDaten(datenneu);

        ende.naechster = neu;
        ende = neu;

        System.out.println("Daten " + datenneu + " wurden eingefuegt.");
    }


    void ausgeben() {
        System.out.println(daten);
        System.out.println();
        if (naechster != null)
            naechster.ausgeben();
    }
}

public class Listev2 {


    public static void main(String[] args) {

        Listenelement listenAnfang = new Listenelement();

        listenAnfang.setDaten("Element 1");

        for (int element = 2; element < 4; element++)
            listenAnfang.anhaengen("Element " + element);

        listenAnfang.ausgeben();
    }


}
Allerdings würde es wohl Sinn machen, den Anfang und das Ende einer Liste außerhalb der "Listenelement"-Klasse zu speichern.
 
S

Saylles

1Fragen haette ich da noch


void setDaten(String datenneu) {
daten = datenneu;
ende = this;
}


ende = this; // was passiert da mir war nicht bewusst das das so funktinoert ich kenne bisher nur this.variablelnamen.
 
Tarrew

Tarrew

"this" ist die Referenz auf das eigene Objekt.
Wenn du also
Java:
neu.setDaten(datenneu);
aufrufst, dann bewirkt "ende = this", dass das Attribut "ende" auf sich selbst zeigt (weil das neuste Element ja immer das Ende ist).
 
S

Saylles

ah okay
wie gesagt so kannte ich das nicht.

ok kapiert glaube ich ich werde mir den code nochmal anschauen und gucken ob ich das alles nachvollziehen kann.
ich danke dir aufjedenfall vielmals
 
J

JustNobody

Wobei ich den Code für relativ dubios halte:

a) Was direkt ins Auge fällt: Was erwartet ihr von einer Methode, die setDaten heisst? Also da mehr zu machen, als den Wert von Daten zu setzen halte ich für fahrlässig. Da wundern mich Verständnisprobleme nicht!

b) Wozu diese ende Variable in der Klasse Listenelement? Was genau ist eure Erwartungshaltung zu dem Inhalt einer solchen Variablen? Ihr habt mehrere Lustenelemente: Was meint ihr, soll da in jedem Element in ende gespeichert sein, so dass es Sinn macht? Oder um es gleich anders zu benennen: Der Verweis auf das letzte Element einer Liste: Wozu gehört der? Ist das eine Eigenschaft einer Liste oder eines Listenelements? (Hat Tarrew ja auch schon angesprochen ... möchte ich nur noch einmal erneut zur Sprache bringen!)

Also als wichtige Kernpunkte folgendes immer im Kopf behalten und prüfen:
- Stimmen die Bezeichner, d.h. besagen diese genau, was sich hinter dem Bezeichner verbirgt? Also speichert die Variable das, was der Name suggeriert? Macht eine Methode genau das, was der Name aussagt?
- Sind die Daten genau da, wo sie hin gehören oder muss etwas evtl. restrukturiert werden?
 
S

Saylles

Oh eine sache noch fiel mir jetzt erst auf.

ende.naechster ich kannte das mit dem punkt operator nur im eine methode in einem objekt aufzurufen.
Wird hier ende und naechster die referenz auf neu gelegt oder was macht der befehl
 
Tarrew

Tarrew

ende.naechster = xyz weißt dem Attribut "naechster" des Objektes "ende" einfach nur einen neuen Wert zu.
Mit objekt.attribut kannst du also auch zugreifen, solange die Sichtbarkeit der Attribut das zulässt.
 
S

Saylles

Wobei ich den Code für relativ dubios halte:

a) Was direkt ins Auge fällt: Was erwartet ihr von einer Methode, die setDaten heisst? Also da mehr zu machen, als den Wert von Daten zu setzen halte ich für fahrlässig. Da wundern mich Verständnisprobleme nicht!

b) Wozu diese ende Variable in der Klasse Listenelement? Was genau ist eure Erwartungshaltung zu dem Inhalt einer solchen Variablen? Ihr habt mehrere Lustenelemente: Was meint ihr, soll da in jedem Element in ende gespeichert sein, so dass es Sinn macht? Oder um es gleich anders zu benennen: Der Verweis auf das letzte Element einer Liste: Wozu gehört der? Ist das eine Eigenschaft einer Liste oder eines Listenelements? (Hat Tarrew ja auch schon angesprochen ... möchte ich nur noch einmal erneut zur Sprache bringen!)

Also als wichtige Kernpunkte folgendes immer im Kopf behalten und prüfen:
- Stimmen die Bezeichner, d.h. besagen diese genau, was sich hinter dem Bezeichner verbirgt? Also speichert die Variable das, was der Name suggeriert? Macht eine Methode genau das, was der Name aussagt?
- Sind die Daten genau da, wo sie hin gehören oder muss etwas evtl. restrukturiert werden?

ich muss vorweg sagen ich uebe das hier momentan.
Ich habe einige Themen schon durch genommen und an Hand der bekannten Themen lerne ich so immer weiter

Es ware wirklich super wenn du deine Kritik anhand von Beispielen mir naeher bringst also Code beispielen da es sonst schwierig ist fuer mich zufolgen.
 
J

JustNobody

ich muss vorweg sagen ich uebe das hier momentan.
Das ist auch super! Das ist keine Kritik an Dir! Ich finde es super, dass Du Dich mit der Thematik auseinander setzt und hoffe, dass wir Dir weiter helfen können, so dass Du auch Spaß an der Software Entwicklung hast.

Das sollen nur Hinweise sein, in der Hoffnung, dass diese Dir zukünftig auch weiter helfen.

Es ware wirklich super wenn du deine Kritik anhand von Beispielen mir naeher bringst also Code beispielen da es sonst schwierig ist fuer mich zufolgen.
In dem Bereich ist aus meiner Sicht nicht viel zu verdeutlichen. Zu a): Eine Methode setDaten setzt nur Daten. Also schlicht etwas wie:
Java:
public void setDaten(String daten) {
    this.daten = daten;
}
Wenn Du auch das Ende setzen willst, dann ist das eben sowas wie:
Java:
public void setDatenAndEnd(String daten) {
    this.daten = daten;
    this.ende = this;
}
Bezüglich b): Wenn Du das Ende einer Liste haben willst, dann ist die Frage: Was genau ist das? Jede Liste hat genau ein Ende. Das speichert man also einfach in der Liste selbst. Es in dem ListenElement zu speichern würde bedeuten, dass jedes ListenElement ein Ende haben würde.... Das scheint mir bei Dir aber nicht der Fall zu sein.

Somit hat man dann bei der Liste eine Klasse wie:
Java:
public class StringList {
  private class Node {
    public String data;
    public Node next;
    public Node(String data) {
      this.data = data;
      next = null;
    }
  }
 
  private Node start; // start of list
  private Node end; // end of list
 
  public StringList() {
    start = null;
    end = null;
  }
 
  public void add(String data) {
    Node node = new Node(data);
    if (start == null) {
      start=node; // Liste war leer, also node ist erster und letzter Node.
      end=node;
    } else {
      end.next = node; // Neuen Node ans Ende anhängen
      end = node;      // Neuer Node ist Ende der Liste.
    }
  }
}
Also das ist jetzt hier im Editor ohne viel drüber nachzudenken entstanden.

Namen:
StringList - Es ist ja nicht nur eine List, sondern es werden Strings gespeichert. Also gleich den Namen entsprechend gewählt.
Dann die Variablen innen drin: start / end ... first / last wäre evtl. besser. Aber das hängt von der Betrachtung her. Ist es das erste und letzte Element oder ist es der Anfang / Ende der Liste? Da es vom Typ Node ist, wäre first/last einleuchtender ...

Wo gehört was hin?
Anfang / Ende der Liste sind Attribute der Liste. Ein Node bei der einfach verketteten Liste hat nur die Daten und das nächste Element.

Aufbau Klassen:
Dann das Listenelement (bei mir Node): Das ist eine interne Sache. Von außen willst Du nur die Liste haben. Wie die Daten innen organisiert sind, ist ein Implementierungsdetail und daher uninteressant.

Methoden kann man da rein setzen, aber teilweise ist es unkritisch. Setter/Getter würde ich da eher weg lassen und die Liste greift direkt auf die Elemente zu, also in dem Code bei mit in add das end.next = node;
Hier ist eine andere Implementation aber nicht falsch oder so. Das ist also eine Präferenz von mir.

Das wäre es etwas ausführlicher.
 
S

Saylles

Java:
class Node {

    String daten;

    Node next, before;

    Node(String daten) {
        this.daten = daten;
        next = null;
        
    }
    void setbefore(Node before) {
        this.before = before;
    }
    Node getbefore() {
        return before;
    }

    void setNext(Node next) {
        this.next = next;
    }

    Node getNext() {
        return next;
    }

    String getDaten() {
        return daten;
    }

}

class Liste1 {

    Node listenAnfang = new Node("Element 1");

    Liste1() {

    }

    public void newElement(String daten) {
        Node neuesEle = new Node(daten);
        neuesEle.setbefore(neuesEle);
        Node letztesEle = getLetzteListe();
        letztesEle.setNext(neuesEle);

    }

    public Node getLetzteListe() {

        Node element = listenAnfang;
        while (element.getNext() != null) {
            element = element.getNext();
        }
        return element;
    }
    
    public void backElement() {
        
    }

    public void output() {
        Node element = listenAnfang;
        while (element != null) {
            System.out.println(element.getDaten());
            element = element.getNext();
        }

    }
    
    public void rewind() {
        Node element = getLetzteListe();
        while (element != null) {
            System.out.println(element.getDaten());
            element = element.getbefore();
        }
        
    }

}

public class Listev_2_5_3 {

    public static void main(String[] args) {

        Liste1 liste = new Liste1();

        for (int element = 2; element < 20; element++)
            liste.newElement("Element " + element);
        liste.output();
        
        // liste.rewind();

        
    }

}
So ich habe mit meinem Dozenten gesprochen ich darf eine eigene Liste schreiben und dies fand ich als sehr angenehm. Die liste soll ich rueckwarts laufen lassen.
Vielleicht findet wer von euch den fehler.
Wenn ich die Methode rewind ausfuhre bekomme ich nur Element 19 in dauerschleife
 
C

CSHW89

In der Methode "newElement" setzt du "before" des neuen Elements auf das neue Element. Ich nehme an, du willst das neue Element hinter das letzte einfügen. Dann muss "before" von diesem neuen Element auf das zuvor letzte Element gesetzt werden.
 
S

Saylles


public void newElement(String daten) {

Node neuesEle = new Node(daten);
Node letztesEle = getLetzteListe();
Node previousEle = letztesEle;
previousEle.setbefore(letztesEle);
letztesEle.setNext(neuesEle);

}

habe das jetzt so angeaendert. selbe problem
 
S

Saylles

ach das geht ja auch nicht ist mir grade klar geworden... bekomme langsam nen blutsturz
 
S

Saylles

Java:
class Listelement {

    String daten;
    Listelement nextEle, prevEle;

    void setDaten(String datenNeu) {
        daten = datenNeu;
        prevEle = this;
        nextEle = null;

    }

    Listelement newElement(String datenNeu) {
        Listelement prevEle = this;
        
        nextEle = new Listelement();
        this.prevEle = prevEle;
        nextEle.setDaten(datenNeu);
        System.out.println("Daten " + datenNeu + " wurden eingefügt");

        return nextEle;

    }

    void output() {
        System.out.println(daten);
        if (nextEle != null) {
            nextEle.output();
        }

    
        
    }
    void rewind() {
        System.out.println(daten);
        while (prevEle!=null) {
            prevEle.rewind();
        }
    }
}

    public class NeueListe {

        public static void main(String[] args) {

            Listelement start = new Listelement();
            Listelement end = new Listelement();
            
            
            start.setDaten("Element 1");
            end = start;
            
            for (int element = 2; element < 5; element++) {
                Listelement newEle = end.newElement("Element " + element);
                end = newEle;
            }
            //start.output();
            end.rewind();
        }

    }
So ich glaube mein Listen Problem fast geloest zu haben. Die Liste soll rueckwarts wiedergegeben werden und sich rekursiv selbst aufrufen bis zum Ende "rewind() "
Kann mir da jemand einen Tip geben eclipse sagt mir es wuerde ein Problem geben bei prevEle.rewind()
 
J

JustNobody

Wenn Eclipse sagt, dass es ein Problem gibt, dann wird Eclipse bestimmt auch das Problem beschreiben....

Und ansonsten nur einmal ein paar Fragen:
in rewind() nutzt Du die Instanzvariable prevEle in einer while Schleife. Kann diese Variable in der while Schleife null werden?

Du kannst es ja mit der Methode output vergleichen und schauen, was Dir auffällt....
 
S

Saylles

Java:
class Listelement {

    String daten;
    Listelement nextEle, prevEle;

    void setDaten(String datenNeu) {
        daten = datenNeu;
        prevEle = null;
        nextEle = null;

    }

    Listelement newElement(String datenNeu) {
        Listelement prevEle = this;
        this.prevEle = prevEle;
        nextEle = new Listelement();
    
        nextEle.setDaten(datenNeu);
        System.out.println("Daten " + datenNeu + " wurden eingefügt");

        return nextEle;

    }

    void output() {
        System.out.println(daten);
        if (nextEle != null) {
            nextEle.output();
        }

    
        
    }

}

    public class NeueListe {

        public static void main(String[] args) {

            Listelement start = new Listelement();
            Listelement end = new Listelement();
            Listelement prev = new Listelement();
            
            start.setDaten("Element 1");
            end = start;
            
            for (int element = 2; element < 20; element++) {
                prev = end;
                Listelement newEle = end.newElement("Element " + element);
                end = newEle;
            }
            start.output();
            
            while (prev.prevEle != null) {
                prev.output();
                prev = prev.prevEle;
            }
            
        }

    }
also Fehler behoben und code ueberarbeitet.
jetzt springt er staendig von 18 auf 19 in dauerschleife
 
J

JustNobody

Also Dein Code ist absolut unstimmig. Beschreibe doch einmal, was prevEle und nextEle in ListenElement beinhalten sollen!

Und dann mal Dir doch einmal auf einem Zettel genau auf, was Du zuweist oder eben nicht...
Und die Logik ist generell seltsam. setDaten setzt die beiden oben angesprochenen Variablen? Ist etwas verwirrend...
 
S

Saylles

Über den Sinn machen ich mir bei den Übungesaudgaben langsam keine Gedanken mehr
Er soll die Liste halt rückwärts wieder geben. Ich finde den Fehler einfach nicht.
 
J

JustNobody

Also meine Frage drehte sich um Dein Verständnis. Ohne ein vernünftiges Verständnis bringt Dir dies hier aus meiner Sicht schlicht nichts.

Schau Dir einmal doppelt verkettete Listen an, versuch zu verstehen, was die Referenzen in jedem Element für einen Sinn machen und dann überlege Dir einmal, wie z.B. eine Liste mit 3 Elementen aussieht ...

Wenn Du das hast (In der Theorie, auf einem Zettel), dann kannst Du in Ruhe überlegen, wie Du eine Liste gestalten kannst und wie das Einfügen funktionieren müsste (Aber erneut: Ohne Code, nur auf einem Zettel!)

Dann können wir über Implementationen reden. Aber ohne ein Verständnis von dem, was du da machst, ist die Chance auf einen Erfolg aus meiner Sicht wirklich gleich Null.
 
S

Saylles

Das Problem ist das Grundgerüst ist nicht von mir. Ich persönlich würde das auch anders machen halt mit nodes zum Beispiel. Jedoch ist das die Aufgabe und die soll ich lösen. Ich hab halt am Anfang des Post den original code schonmal gepostet . Ich habe das Thema Listen schon verstanden zumindest glaub ich das.
Aber diese Aufgabe bringt mich zum verzweifeln. Ich habe halt den Hinweis bekommen das das Thema weniger die Liste ist sondern eher wie einzelne Methoden arbeiten, quasi wie greife ich auf Variablen zu wie veraendere ich diese etc.
Ich habe diesen Code schon so oft geändert das ich einfach nur noch ein Brett vor dem Kopf habe und dies selber merke sobald ich den Code nur sehe.
Deswegen Frage ich hier ob jemand mir einen Hinweis geben kann warum er mir nur noch 18 & 19 ausgibt.
 
F

fhoffmann

Code:
    Listelement newElement(String datenNeu) {
        Listelement prevEle = this;
        this.prevEle = prevEle;
        // ...
Danach zeigt this.prevEle auf this. Das kann doch nicht stimmen!
 
J

JustNobody

Also ich bin erst einmal unterwegs ... falls niemand dir einen Link zu einer Doppelt verrotteten Liste schickt dann suche ich später was raus. Wobei du auch einfach mal suchen kannst. Wikipedia wird da bestimmt etwas haben...

Schau dir das erst einmal an damit du verstehst, was überhaupt passieren soll. Ohne Verständnis einer solchen Liste wirst du darauf keine Aktionen ausführen können ....
 
J

JustNobody

Lol, die doppelt verrottete Liste :) Hab ich eben gar nicht gesehen, was mein Handy da an Auto Korrektur gemacht hat ...

Also die doppelt verkettete Liste wird z.B. hier ganz kurz vorgestellt:
https://de.wikipedia.org/wiki/Liste_(Datenstruktur)#Doppelt_verkettete_Liste

Wichtig ist mir da das Bild -> Da kannst Du sehen, wie die Referenzen ("Zeiger") zwischen den Elementen sein müssen.

Also wenn Du eine Liste hast mit Anfang und Ende, dann ist am Anfang beide null.
Wenn Du nun ein Element einfügst, zeigen Anfang und Ende der Liste auf dieses erste Element.
prev und next dieses Elementes zeigen auf null. Anfang und Ende zeige ich jetzt mal nicht aber die Liste:
null <-- 1. Element --> null

Wenn Du jetzt ein zweites Element an das Ende einfügst, dann muss next vom 1. Element auf das neue Element zeigen. Und prev vom neuen Element auf das 1. Element:
null <-- 1. Element <--> 2. Element --> null
Anfang zeigt auf das 1. Element, Ende auf das 2. Element.

Soviel als Erläuterung. Kannst Du nun das Einfügen bei Dir so schreiben, dass die Referenzen immer korrekt sind?
 
Thema: 

Erklaerung Listen

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben