Die Iterator-Schnittstelle
Habe ich eine universitäre Aufgabe, die mich verpflichtet, die Implementierung einer inneren Klasse implementiert das Iterator-interface. Der iterator arbeitet auf einer single-Link-Liste Superklasse.
Derzeit meine innere Klasse sieht wie folgt aus:
private class ListIterator implements Iterator<V>{
Node temp;
boolean nextCalled = false;
ListIterator(Node fo){
this.temp = fo;
}
@Override
public boolean hasNext() {
if(temp != null){
return true;
}
return false;
}
@Override
public V next() {
nextCalled = true;
return temp.getReprValue();
}
@Override
public void remove() {
if(nextCalled && hasNext()){
nextCalled = false;
removeElement(temp.getReprKey());
temp = temp.getNext();
}
}
}
Nun mein problem ist, dass die hasNext () - Methode gibt true zurück, auch wenn die Liste wirklich leer ist. Alles andere scheint zu funktionieren. Habe ich wohl übersehen, ein Logik-Fehler irgendwo, aber ich kann es nicht finden mich.
next
Methode soll nicht nur die Rückkehr Wert, aber irgendwie bewegen iterator in die nächste position. Ihre Umsetzung nur speichert ein flag.- Sollte nicht der Wert von
temp
geändert werden in Ihremnext()
Methode? - Auf einer seitlichen Anmerkung, es gibt bereits ein interface mit dem Namen
ListIterator
im gleichen Paket wie die Iterator... so möchten Sie vielleicht einen anderen Namen wählen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Verändert Ihre Umsetzung zu reflektieren, was das Iterator-Vertrag braucht. Sie müssen sich daran zu erinnern, dass Sie müssen in der Lage sein zu iterieren über alle Elemente der Kollektion, D. H.,
next()
beginnen soll ab dem ersten element und nach jedem Anruf muss es ändern die aktuelle nächste element auf das nächste element in der Liste aus, oder werfen eine Ausnahme, wenn es keine.Es ist gut zu Lesen, die Iterator-interface doc zu undestand, wie Sie brauchen, um es zu implementieren und starten von dort aus.
Müssen Sie verfolgen, wo Sie in Ihrer Liste haben, implementieren Sie eine
cursor
oder wenn Ihr Knoten in die verkettete Liste sind sich Ihrernext
, fragt Sie einfach, wenn Sie ein Nächstes element.Wenn der cursor größer ist dann die Länge /Ihr Knoten hat keine
next
Sie false zurück im hasNext().Tun all dies in Ihrer
hasNext()
Methode. Denken Sie daran, es ist okay, haben next() eine exception werfen, wennhasNext()
wäre falsch - Sie müssen also sicher sein, dass die einzige Zeit, es wird eine Ausnahme ausgelöst.Als ich weiß nicht, die zugrunde liegende Datenstruktur der Liste, ich kann Ihnen nicht sagen, welche der beiden besser sein wird.
hasNext
gibt true zurück, wenn der aktuelle Knoten (temp
) ist nichtnull
.Wenn Ihr verkettete Liste-Implementierung verwendet ein header-Knoten, dann wird der Konstruktor erhält immer
fo!=null
undhasNext
zurücktrue
obwohl die Liste leer ist. Sie sollten erwägen, diese Tatsache in Ihrer Umsetzung.Basierend auf Ihren code, es scheint, dass
kann den trick tun (wenn
header.getNext()==null
für eine leere Liste).Reduzieren einige code, und machen Sie einen Hauch mehr lesbar
temp
zunext
,current
Knoten,macht das update wie folgt Aussehen:
löschen könnte Strom zu null. Wir brauchen nicht, ein flag (vorausgesetzt, wir sind gut mit nichts zu tun, wenn eine person löscht, die vor dem Aufruf der ersten
getNext()
. Heck, wenn wir wirklich wollen, gehen für das gold, habenremove()
werfen einIllegalStateException
wenncurrent == null
.public static void main(String[] args)
in jedem der Beispiele, und diese Antwort war gut genug für den Fragesteller, damals, als ich antwortete es vor vier Jahren. Vielleicht könnten Sie das noch näher erläutern?Node current
im Anfang desgetNext()
Funktion, dann würden Sie haben, um es jedes mal, wenn diegetNext()
- Funktion aufgerufen wird (oder null sein). Was Sie legen Sie es aus, vorausgesetzt, Sie haben eineIterator
können, Holen Sie sich die zweite - element in einer Sammlung, müssen deklariert werden, die außerhalb dergetNext()
Methode. So der Dritte Aufruf zugetNext()
kann etwas zurückgeben "nach" der zweite Anruf, etc. In meinem Beispiel, diecurrent
hält, was Sie haben, und dienext
hält die nächste aktuelle. Dies vereinfacht die Logik für Iteratoren auf leere Listen.next()
(und für einige Arten von iterator-design, das gleiche). Dieget
Teil zeigt, dass es Fortschritte der iterator (was effektiv ist das Objekt, halten die konzeptionelle index, der die Sache transversed) UND gibt den Wert an, den index, den Sie transversed in. Einige Iteratoren verwendennext()
ohne Rückkehr, und einige nutzennext()
in einer identischen Art und Weise zugetNext()
wie ich es beschreiben oben. Es gibt wenig Standardisierung von Technologien.