www.mikrocontroller.net

Forum: PC-Programmierung Java Listen. Verstehe angehängte Methode nicht


Autor: Christin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen, ich habe eine Frage zu Listen in Java.
Ich habe hier einen Code, mit dem man Listen erstellen kann.
Ein Beispiel ist in der Main funktion.
Man macht eine neue Liste mit

ConsList l = new ConsList();

und kann dann Sachen einfügen z.B:

l.insert("Hallo")
l.insert("DU!!!")

und dann die liste mit

print(l) ausgeben.

Wie gesagt in der main Funktion sind dazu Beispiele.

Ich verstehe die Methode insert nicht.
Dort wird erst eine neue Zelle angelegt, mit dem Inhalt, den man 
übergibt.
Cons cons = new Cons(obj);

Dann wird diese Zelle auf head zeigen. Also prinzipiell zeigt dann jede 
Zelle auf Head.

Head aber wird im nächsten Schrit gleich cons gesetzt.
Da alle Zellen auf head zeigen, head gleich cons gesetzt wird und cons 
der Inhalt der letzten Zelle ist, heißt das doch alle Zellen  zeigen auf 
die letzte.
Aber wo ist da der Sinn? Das kann  doch so garnicht verstanden werden!?

Es wäre schön, wenn ihr mir helfen könntet ;)
Danke

public class Cons 
{
  public Object obj; // das Objekt in dieser Zelle
  public Cons next;  // Verweis auf die naechste Zelle
  public Cons(Object obj) {
    this.obj = obj;
    next = null;
  }
}

public class ConsList
{
  private Cons head, foot; // Kopf und Fuss der Liste
  public ConsList() { head = foot = null; /* neue leere Liste */ }
  public boolean contains(Object obj) { return contains(head, obj); }
  protected boolean contains(Cons cons, Object obj) {
    if (cons == null) return false;
    else if (cons.obj == obj) return true;
    else return contains(cons.next, obj);
  }
  public void print() {
    System.out.print("Liste [");
    print(head);         // rekursive Ausgabe der Cons-Zellen
    System.out.println("]");
  }
  protected void print(Cons cons) {
    if (cons == null) return ;  // letzte Zelle erreicht
    System.out.print(cons.obj); // Objekt ausgeben
    if (cons.next != null) {
      System.out.print(", ");
      print(cons.next);       // Rekursiv weiter 
    }
  }
  public void insert(Object obj) {
    Cons cons = new Cons(obj);  // neue Cons-Zelle
    cons.next = head;      // vorne anfuegen..
    head = cons;        // .. und Kopf der Liste anpassen
    if (foot == null) foot = cons; // eventuell auch den Fuss
  }
  public void append(Object obj) {
    Cons cons = new Cons(obj);  // neue Cons-Zelle
    if (foot == null) head = foot = cons; // genau eine Cons-Zelle
    else { // hinten anfuegen und Fuss anpassen
      foot.next = cons;
      foot = cons;
    }
  }
  public void remove(Object obj) {
    if (head == null) return ;
    if (head.obj == obj) {
      if (head == foot) foot = head = null;
      else head = head.next;  // erste Cons-Zelle entfernen
    } else remove(head, head.next, obj);
  }
  protected void remove(Cons prev, Cons cons, Object obj) {
    if (cons == null) return ;
    if (cons.obj == obj) {
      // vorherige Cons-Zelle auf Nachfolgende zeigen lassen,
      // somit faellt 'cons' aus der Liste
      prev.next = cons.next;
      if (foot == cons)     // evtl. Fuss anpassen
        foot = prev;
    } else remove(cons, cons.next, obj);
  }
  public boolean isEmpty() { return head == null;  }
  public Object removeHead() {
    if (head == null) return null;
    Object res = head.obj;
    if (head == foot) head = foot = null;
    else head = head.next;
    return res;
  }

  public static void main (String ... args) {
    // Kleines Testprogramm fuer Listen:
    ConsList l = new ConsList();
    System.out.println("leer? " + l.isEmpty());
    String s1 = "Hallo", s2 = "Welt";
    l.insert(s1);
    System.out.println("leer? " + l.isEmpty());
    l.print();
    l.insert(s2);
    l.print();
    l.remove(s2);
    l.print();
    l.append(s2);
    l.print();
    l.remove(s2);
    l.remove(s1);
    l.print();
    System.out.println("leer? " + l.isEmpty());
  }
}



Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
- insert erzeugt zuerst ein neues Listenelement
- weist dem next-Zeiger des neuen Elementes die bisherige Liste zu
- weist dem Listenanker das neue Element zu

Ergo: insert fügt ein neues Element vorne an die Liste an - oder anders 
ausgedrückt: es implementiert eine push-Operation.

Autor: progger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du solltest Dich mal etwas näher mit verketteten Listen auseinander 
setzen.
Die Funktion macht nix anderes als ein neues Objekt an den Anfang der 
Liste anzufügen und danach dieses Objekt als Anfang zu deklarieren.
Ist also ganz normal.
Das vorherige Anfangsobjekt ist dann das zweite in der Liste und hängt 
am "next" pointer des ersten Objekts.

Autor: Unbekannter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Dann wird diese Zelle auf head zeigen. Also prinzipiell zeigt dann jede
> Zelle auf Head.
>
> Head aber wird im nächsten Schrit gleich cons gesetzt.

Na, dann stimmt die Theorie von verschiedenen Profs. ja doch, dass Java 
das grundsätzliche Verständnis für Zeiger verhindert.

Also, kurze Erklärung:

"head" ist eine Zeiger. In "head" steht praktisch eine Speicheradresse 
drin, an der ein bestimmtes Objekt zu finden ist.

Ein Listenelemeten besteht aus dem Tupel (obj, next).

"obj" ist quasi ein Zeiger auf das Datenobjekt, "next" ist ein Zeiger 
auf das Nächste Listenelement.

In Java sind fast alle Variablen in Wirklichkeit Zeiger (bis auf die 
Integraltypen).

Wenn ein neues Element in die Liste eigefügt wird, wird der 
"next"-Zeiger auf den Wert des "head"-Zeigers gesetzt. Also findet man 
unter "next" nun das gleiche Objekt wie unter "head".

Allerdings kann man das neue Listen-Element noch niergends finden, also 
wird der "head"-Zeiger anschließen auf das neue Listen-Element gesetzt.

Ganz einfach und logisch.

Autor: Christin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Angenommen ich tippe
insert("Hallo") ein.
Dann wird das Listenelement erzeugt, klar.
Dem next Zeiger von "Hallo" wird dann auf "head" gesetzt ( cons.next = 
head)
und heat wirderrum wird mit cons gleichgesetzt. Also "Hallo" zeigt auf 
sich selber? Mir ist das nicht klar inwiefern das hier erfüllt wird, 
könntet ihr das etwas genauer sagen?

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum debuggst du dich nicht einfach mal durch den Code? Dann kannst du 
dir alles angucken und verstehst hinterher, was passiert...

Autor: Christin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie meinst du das? Wie kann ichd as mit Eclipse machen? Und inwiefern 
kann ich das dann sehen?

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jeder ordentliche Debugger erlaubt zumindest Objekte anzusehen, sehr oft 
ist es sogar möglich, sie während der Debug-Session zu verändern. 
Natürlich kann man auch Haltepunkte setzen, an denen der Debugger das 
Programm stoppt, damit du nachsehen kannst, was los ist. Wenn du im 
Einzelschrittmodus durch dein Programm tackerst, kannst du sogar Schritt 
für Schritt sehen, was passiert.

Wie das mit Eclipse geht weiß ich nicht - noch nie benutzt. Sieh eben 
mal in der Dokumentation nach, wie man den Java-Debugger anwirft. Da 
kannst du fürs Leben lernen...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.