2016-04-18 3 views
1

Ich implementiere einen Binärbaum. Ich habe ein Iterator-Klasse für den Baum, der Iterator implementiert, aber ich muss es den Baum für den Konstruktor geben:JAVA - Erstellen eines Iterators für Baumdatenstruktur, der Iterator implementiert und Kopfknoten bekommt

public class AvlIterator implements Iterable<Integer>{ 
    public Iterator<Integer> iterator(AvlTree avlTree){ 
    //here i construct the iterator class, with the avlTree inside. 
    } 
} 

Aber die Schnittstelle nicht jedes Objekt in seinem Konstruktor bekommt. Es sagt mir, diese Signatur hinzuzufügen:

public Iterator<Integer> iterator(); 

Also, was mit meiner Implementierung falsch ist? Auf der einen Seite brauche ich das Tree-Objekt, um meine Operationen auszuführen, auf der anderen Seite sagt Java mir, dass ich Dinge nicht richtig mache.

Antwort

3

Wenn Sie die AvlIterator eine innere Klasse Ihrer AvlTree Klasse machen, wird es Zugriff auf die AvlTree Instanz haben, und Sie müssen nicht alles auf die iterator()-Methode übergeben. Auf diese Weise können Sie die von der Schnittstelle Iterable benötigte Methode implementieren.

Eigentlich wäre es sinnvoller, wenn AvlTree selbst implementiert Iterable<Integer>. AvlIterator würde implementieren.

public class AvlTree implements Iterable<Integer> 
{ 

    ... 
    class AvlIterator implements Iterator<Integer> 
    { 
     ... here you have access to the properties of the enclosing AvlTree instance ... 
    } 
    ... 

    public Iterator<Integer> iterator() 
    { 
     return new AvlIterator(); 
    } 
    ... 

} 
+0

Oder besser verwenden Sie eine anonyme Klasse innerhalb der Methode iterator(), die Iterator erweitert und das zurückgibt. Und AvlTree muss Iterable erweitern Madhusudhan

+0

Dies ist, wie die meisten Iteratoren in der JVM implementiert werden, so ist es wahrscheinlich der richtige Weg zu gehen. –

+0

@ArnaudDenoyelle - Willst du sagen, dass anonyme Klassen die bevorzugte Methode ist oder sind innere Klassen die bevorzugte Methode? – Madhusudhan

0

Um Ihre Frage zu beantworten: „Was mit meiner Implementierung falsch ist“, Iterable<T> Schnittstelle eine Methode aufgerufen hat Iterator<T> iterator(), die von der Klasse implementiert werden muss, die diese Schnittstelle implementiert. Wenn Sie die Methodensignatur sehen, wird kein Argument benötigt. Wenn Sie also eine Methode mit einem Argument implementieren, überschreiben Sie diese Methode praktisch NICHT, sondern fügen eine andere überladene Methode hinzu. Daher beschwert sich der Compiler, dass Sie die Methode implementieren müssen.

Deshalb ist es immer empfehlenswert, mit @Override an jede Methode zu kommentieren, von der Sie glauben, dass Sie sie außer Kraft setzen. Dies wird abgefangen, wenn die Methodensignatur nicht mit der Methode übereinstimmt, die Sie überschreiben möchten.

Zum Beispiel könnte viele mit der Art des Fehler der überwiegenden equals Methode tun sie für zwingende statt Object, die zwingenden nicht wirksam ist. Ohne @Override, alles mit Kompilieren, aber es kann bizarre Bugs erzeugen, wenn diese Art von Objekten im Collection-Framework verwendet werden oder sogar wenn man equals-Methoden verwendet.

public boolean equals(Employee employee) { 
    //amazing logic to find equality 
} 

ist eine falsche Implementierung und Compiler ohne @Override Anmerkung entweichen kann.