# Eigener Iterator für LinkedList



## mamelinchen (19. Mai 2009)

Verstehe das Thema noch nicht ganz und finde auhc nicht viel dazu.

HAbe eine erste Implemtentierung gemacht, die natürlich nicht funktioniert.

Welche Sachen sollte ich beachten?


```
import a01.AbstractPerson;
import a01.Person;
import a02.List;

public class LinkedList implements List {

	protected Node head;
	protected Node tail;
	int size;

	public LinkedList() {
		this.tail = new Node(null, tail);
		this.head = new Node(null, tail);
		this.size = 0;
	}
	
	protected class IteratorImpl implements Iterator<Node> {
		public Node actual;

		public IteratorImpl(Node actual) {
			this.actual = actual;
		}

		public boolean hasNext() {
			return actual!=null;

		}

		public Person next() {
			return actual.getPerson();
		}

		public IteratorImpl iterator() {
			IteratorImpl iterator=new IteratorImpl(head.next);
			return iterator;
		}

	}

	protected class Node {

		public Node next;
		public Person person;

		public Node(Person person, Node next) {
			this.next = next;
			this.person = person;
		}

		public Node getNext() {
			return this.next;
		}

		public Person getPerson() {
			return this.person;
		}
	}

	public int clear() {
		int zähle = 0;
		Node node = head;
		while (node != tail) {
			zähle++;
			node = node.getNext();
		}
		head.next = tail;
		return zähle;
	}

	public Person get(int i) {
		if (i < 0) {
			throw new IndexOutOfBoundsException();
		}
		Node node = head;
		while (i-- > 0) {
			if (node.next == tail) {
				throw new IndexOutOfBoundsException();
			}
			node = node.getNext();
		}
		return node.person;
	}
[COLOR="YellowGreen"]//Mittels Iterator Liste durchlaufen und an Stelle i einfügen
Ist das richtig oder vollkommen falsch?
Sollte ich es mit iterator() machen?Aber wo wende ich den an?Speziell?[/COLOR]

	public void insert( int i,AbstractPerson person) {
		if (i <= 0) {
			throw new IndexOutOfBoundsException();
		} else {
			IteratorImpl iterate =new IteratorImpl(head);
			int stelle = 0;
			while (iterate.hasNext()) {
				stelle++;
				if (stelle == i) {
					Node g = new Node((Person) person, iterate.actual.next);
					iterate.actual.next = g;
				}

			}
		}
		size++;
	}


	public void remove(int i) {
		if (i < 0) {
			throw new IndexOutOfBoundsException();
		} else if (i == 0) {
			System.out.println("Entfernen ist nicht möglich");
		} else {
			Node node = head;
			int stelle = 0;
			while (node != tail) {
				stelle++;
				if (stelle == i) {
					node.next = node.getNext().getNext();
				}
				node = node.getNext();
			}
		}
		size--;
	}

	public void reverse() {
		int i = 0;
		Node prev = head;
		Node actualNode = head;
		Node nextNode = actualNode.next;
		while (i <= size) {
			prev = actualNode;
			actualNode = nextNode;
			nextNode = actualNode.next;
			actualNode.next = prev;
			i++;
		}
		nextNode = head;
		head = tail;
		tail = nextNode;
		tail.next = prev;
	}

	public int size() {
		return size;
	}

	public String toString() {
		String string = "[";
		Node node = head.next;
		while (node != null && node.getPerson() != null) {
			string += node.getPerson().toString();
			node = node.getNext();
			if (node != null && node.getPerson() != null) {
				string += " ; ";
			}
		}
		return string + "]";
	}
	
	public static void main(String[] args) {
		LinkedList alpha = new LinkedList();
		alpha.insert(1, new Person("Tobias", "Salomon", 1985, "12423"));
		alpha.insert(2, new Person("Melanie", "Mieritz", 1987, "10117"));
		alpha.insert(2, new Person("Antje", "Roloff", 1980, "12567"));
		alpha.insert(1, new Person("Jennifer", "Hübner", 1986, "12478"));
		System.out.println(alpha.size());
		System.out.println(alpha);
		alpha.reverse();
		System.out.println(alpha);
		System.out.println(alpha.get(2));
		alpha.remove(2);
		System.out.println(alpha);
		System.out.println(alpha.clear());
		System.out.println(alpha);
	}
}
```


----------



## mamelinchen (19. Mai 2009)

Habs jetzt.

Aber mein Einfügen geht nicht. Was mach ich falsch?


```
public void insert(int i, AbstractPerson person,IteratorImpl iterate) {
		if (i <= 0) {
			throw new IndexOutOfBoundsException();
		} else if (head.next == tail) {
			Node nu = new Node((Person) person, tail);
			head.next = nu;
		} else {
			int stelle = 0;
			while (iterate.hasNext()) {
				stelle++;
				if (stelle == i) {
					Node g = new Node((Person) person, iterate.actual.next);
					iterate.actual.next = g;
				}
			}
		}size++;
		
	}
```

Dazu mein Iterator.


```
protected class IteratorImpl implements Iterator<Person> {
		public Node actual;

		public IteratorImpl(Node actual) {
			this.actual = actual;
		}

		public boolean hasNext() {
			return actual!=tail;
		}
		
		public Person next() {
			if (!hasNext()) {
				throw new NoSuchElementException();
			} else {
				Person person = actual.getPerson();
				actual = actual.next;
				return person;
			}
		}
	}
	public IteratorImpl iterator() {
		return new IteratorImpl(head.next);
	}
```

und die Knoten von der Liste:


```
public LinkedList() {
		this.tail = new Node(null, tail);
		this.head = new Node(null, tail);
		this.size = 0;
	}
```


----------



## Marco13 (20. Mai 2009)

Hab wegen der Fragewürdigen Fragestellung (keine Fehlerbeschreibung, kein compilierbarer Code) nurmal kurz draufgeschaut, aber ... wenn ein neues Element eingefügt wird, muss man auch 
vorheriges.next = neues
setzen, das hab ich da jetzt nirgends gesehen...


----------



## SlaterB (20. Mai 2009)

dürfte doch hier sein:
> Node g = new Node((Person) person, iterate.actual.next);
> iterate.actual.next = g;

iterate.actual.next zeigt auf g, g auf das alte iterate.actual.next

ob was davon nicht geht, kann man am einfachsten wirklich zur Laufzeit testen,
vorher + nachher alle möglichen Verknüpfungen ausgeben oder debuggen


----------



## mamelinchen (20. Mai 2009)

Habs, bloss er fügt nicht an die Stelle ein wo er soll:


```
public void insert(int i, AbstractPerson person, IteratorImpl iterate) {
		if (i <= 0) {
			throw new IndexOutOfBoundsException();
		} else {
			int stelle = 0;
			while (iterate.hasNext() && stelle != i) {
				stelle++;
				if (stelle == i) {
					Node g = new Node((Person) person, iterate.actual.next);
					iterate.actual.next = g;
				}
			}
		}
		size++;
	}
```

Beim einfügen mit der Reihenfolge und Stellen:


```
alpha.insert(1, new Person("Tobias", "Salomon", 1985, "12423"),iterate);
		alpha.insert(2, new Person("Melanie", "Mieritz", 1987, "10117"),iterate);
		alpha.insert(2, new Person("Antje", "Roloff", 1980, "12567"),iterate);
		alpha.insert(1, new Person("Jennifer", "Hübner", 1986, "12478"),iterate);
```

Gibt er das aus:
[Jennifer Hübner  1986 12478 ; Antje Roloff  1980 12567 ; Melanie Mieritz  1987 10117 ; Tobias Salomon  1985 12423]

also total hintereinander....

Wie mach ich das ?!

Ich möchte auch meine toString mit dem Iterator durchlaufen. Was ich aber nur bekomme ist:

a07.LinkedList@a90653
a07.LinkedList@a90653??

Bei:



```
public String toString([COLOR="DarkOrange"]IteratorImpl iterate[/COLOR]) {
//ist mein iterator von der Liste, auf die ich toString anwende
		String string = "[";
		while (iterate.hasNext()){
			string += iterate.next().toString();
			if (iterate.hasNext()) {
				string += " ; ";
			}
		}
		return string + "]";
	}
```

wobei der Iterator mit head anfängt und folglich als person null zurückgibt.

Ahhh ich seh das wieder net.


----------



## SlaterB (21. Mai 2009)

prüfe doch im Detail, was beim Einfügen passiert,
zu Beginn von insert schreibst du 
System.out.println("inserte Objekt .. an Position .., kompletter Überblick über Stand der Liste: ............");

> while (iterate.hasNext() && stelle != i) {
> 				stelle++;

wird hier überhaupt zum nächsten Element gesprungen oder nur stelle erhöht?
auf jeden Fall genauso ein Fall fürs Loggen:
System.out.println("Schleifendurchlauf, stelle erhöht auf .., aktueller Iterator zeigt auf Element ..");

nichts bleibt verborgen in so einfachen Programmen, alles ist erklärbar mit dem einfachst-denkbaren Befehl
System.out.println()


----------



## mamelinchen (21. Mai 2009)

ja das hab ich mir auch überlegt, das passiert garnicht!

das heisst ich schreibe:


```
while (iterate.hasNext() && stelle != i) {
    stelle++;
    if (stelle == i) {
          Node g = new Node((Person) person, iterate.actual.next);
          iterate.actual.next = g;
    }
    [COLOR="Orange"]iterate.next();   [/COLOR] >[COLOR="YellowGreen"] //springt zum nächsten knoten und damit kann das einfügen stattfinden^^[/COLOR]
}
```



ja system.out.println ist ein guter freund


aber was bedeutet 
a07.LinkedList@a90653??


----------



## Schandro (21. Mai 2009)

> a07.LinkedList@a90653


Dieser String wurde von der toString() Methode deiner Klasse LinkedList zurückgegeben. Wenn du stattdessen was anderes zurückgeben lassen willst, musst du toString() in deiner Klasse LinkedList überschreiben und was anderes zurückgeben lassen.
In der Klasse Object (von der deine Klasse LinkedList ja schlussendlich erbt) ist toString auf diese Art definiert worden (Klassenname@hashcode).


----------



## mamelinchen (21. Mai 2009)

Kann er das auch zurückgeben, wenn meine toString() der LinkedList-Klasse nicht funktioniert?

Wie oben zu sehen?

Ich hab den Fehler schon gefunden.

Ich iteriere ja auch bei toString () nicht :/

Muss ich noch ändern!


----------



## Schandro (21. Mai 2009)

Du überschreibst toString() nicht.
Du erstellst eine neue Methode
toString(IteratorImpl iterate)


----------



## mamelinchen (21. Mai 2009)

Achjaaaaa!Is ja was andres ,klar.

Ich habs die toString()ja vorher mit Knoten gemacht .

Aber wie soll ich sonst den Iterator benutzen zum Wiedergeben der Liste?


----------



## SlaterB (22. Mai 2009)

total undeutliche Frage, was funktioniert nicht?


----------



## ARadauer (22. Mai 2009)

toString von Node muss auch überschrieben werden...



> toString(IteratorImpl iterate)


nein!


----------



## ARadauer (22. Mai 2009)

```
/**
     * Returns a string representation of the object. In general, the 
     * <code>toString</code> method returns a string that 
     * "textually represents" this object. The result should 
     * be a concise but informative representation that is easy for a 
     * person to read.
     * It is recommended that all subclasses override this method.
     * <p>
     * The <code>toString</code> method for class <code>Object</code> 
     * returns a string consisting of the name of the class of which the 
     * object is an instance, the at-sign character `<code>@</code>', and 
     * the unsigned hexadecimal representation of the hash code of the 
     * object. In other words, this method returns a string equal to the 
     * value of:
     * <blockquote>
     * <pre>
     * getClass().getName() + '@' + Integer.toHexString(hashCode())
     * </pre></blockquote>
     *
     * @return  a string representation of the object.
     */
    public String toString() {
	return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
```
so wirds standardmäßig gemacht.. will man das nicht, muss man genau die methode überschreiben...


----------



## Lexi (22. Mai 2009)

Am besten wäre es, wenn du jeder Methode die eine andere überschreibt ein "@Override" beifügst. Dann weißt du, ob du auch wirklich was überschreibst .


----------



## mamelinchen (23. Mai 2009)

Ich will meinen Listeniterator benutzen zum Wiedergeben der Liste.

Wie mach ich das mit der toString()-Methode?


----------



## mamelinchen (23. Mai 2009)

Oder genauer:

wie verwende ich denn den Iterator dort?
Den kann ich ja nichtmal dort erzeugen oder doch?


----------



## SlaterB (23. Mai 2009)

> Den kann ich ja nichtmal dort erzeugen oder doch? 

den Iterator(?) dort (in der toString()-Methode?) erzeugen?
warum erzeugen, der Iterator ist doch schon da, 

eindeutige Fragen, wo seid ihr..

--------

in einer toString()-Methode kann man über alles Auskunft geben, was das Objekt kennt,
über alles andere nicht,
einfaches Spiel

der Iterator kennt anscheinend nur einen Node, viel mehr gibts auch kaum bei verketteten Listen,
diesen Node könnte man in toString() ausgeben und/ oder Schritt für Schritt nach weiteren Nodes durchlaufen oder was auch immer du benötigst


----------



## mamelinchen (25. Mai 2009)

Das was ich wollte :


```
public String toString() {
IteratorImpl iterate=[COLOR="DarkOrchid"]this[/COLOR].iterator();
		String string = "[";
		while (iterate.hasNext()){
			string += iterate.next().toString();
			if (iterate.hasNext()) {
				string += " ; ";
			}
		}
		return string + "]";
	}
```
Das ich den Iterator mit DER LinkedList erzeuge und durchratter.

Das wollt ich wissen.


----------



## SlaterB (25. Mai 2009)

bei mehr als 1000 Elementen kann eine solche Methode spürbar langsam werden,
verwende lieber StringBuilder statt String + String,
das ist dann 100x schneller


----------



## mamelinchen (25. Mai 2009)

okay thx!


----------

