1

私は学習演習を行っており、イテレータを使用して独自のリンク リストを作成しています。クラスは次のとおりです。

public class LinkedList<T> implements Iterable <T> {
    private Node<T> head;
    private Node<T> tail;
    private int size;

    public LinkedList() {
        head = new Node<T>();
        tail = new Node<T>();
        head.setNext(tail);  
        tail.setPrevious(head);
        size = 0;
    }

    public void append(T element) {
        tail.getPrevious().setNext(new Node<T>(element));
        tail.getPrevious().getNext().setNext(tail);
        tail.getPrevious().getNext().setPrevious(tail.getPrevious());
        tail.setPrevious(tail.getPrevious().getNext()); 
        size++;
    }

    public void prepend(T element) {
        head.getNext().setPrevious(new Node<T>(element));
        head.getNext().getPrevious().setPrevious(head);
        head.getNext().getPrevious().setNext(head.getNext());
        head.setNext(head.getNext().getPrevious());
        size++;
    }

    public void remove(Node<T> nodeToRemove) {
        if(!isEmpty()) {
            nodeToRemove.getPrevious().setNext(nodeToRemove.getNext());
            nodeToRemove.getNext().setPrevious(nodeToRemove.getPrevious());
            nodeToRemove.setNext(null);
            nodeToRemove.setPrevious(null);
            nodeToRemove.setElement(null);
            nodeToRemove = null;
            size--;
        }
    }


    public boolean isEmpty() {
        return size() == 0;
    }

    public int size() {
        return size;
    }   

    public Iterator<T> iterator() {
        return new Cursor<T>(head);
    }

    public String toString() {
        String result = "";

        for(T t : this) {
            result += t.toString() + "\n";
        }

        return result;
    }

    private final class Cursor<E> implements Iterator<E> {
        private Node<E> current;

        public <E> Cursor(Node<E> head) {
            this.current = current;
        }

        public boolean hasNext() {
            return current.getNext().getNext() != null;
        }

        public E next() {
            current = current.getNext();

            return current.getElement();
        }

        public void remove() {
            remove(current);
        }
    }
}

かなりの調査を行った後、イテレータを実装する良い方法は、内部クラスとして実行することです。しかし、カーソル クラスの remove メソッドでコンパイル エラーが発生します。私が得ているエラーはに適用できませんが、型の不一致が原因だと思いremove()ますLinkedList<T>.Cursor<E>) <Node<E>

私はかなり長い間これに取り組んできましたが、何が間違っているのか正確には理解できません。

4

1 に答える 1

2

いくつか間違っていることがあります:

  1. と呼ばれる 2 つのメソッドがありremoveます。removeJava は、パラメーターを取らない内部Cursorクラスを呼び出そうとしていると考えています。次のように参照を修飾する必要があります。

    LinkedList.this.remove(current);

  2. 内部カーソル クラスは非静的です。非静的内部クラスは、それらを作成した外部クラス インスタンスに関連付けられます。基本的に、それらは外部クラス オブジェクトへの親ポインターを維持します。これは反復子の実装には適していますが、ジェネリックの使用方法を変更する必要があります。非静的内部クラスは、親クラスの型パラメーターを使用できます。これは、イテレータの定義を次のように変更できることを意味します。

    private final class Cursor implements Iterator<T>

    自動的に<T>from を使用しLinkedListます。

  3. this.current = current;おそらくあるはずですthis.current = head;

  4. なぜ2 回hasNext呼び出すのですか?getNext()

それが役立つことを願っています。

于 2012-03-22T02:16:35.220 に答える