Ошибка компиляции с универсальными типами Java - PullRequest
1 голос
/ 22 марта 2012

Я делаю учебное упражнение и создаю свой собственный связанный список с итератором. Класс выглядит следующим образом:

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() в LinkedList<T>.Cursor<E>, которую нельзя применить к <Node<E>).

Я боролся с этим в течение достаточно долгого времени, и я не могу понять, что именно не так, я был бы признателен за любые ваши идеи.

1 Ответ

2 голосов
/ 22 марта 2012

Есть несколько неправильных вещей:

  1. У вас есть 2 метода с именем remove.Java думает, что вы пытаетесь вызвать remove во внутреннем классе Cursor, который не принимает параметров.Вы должны квалифицировать ссылку следующим образом:

    LinkedList.this.remove(current);

  2. Ваш внутренний класс курсора не является статичным.Нестатические внутренние классы связаны с экземпляром внешнего класса, который их создал.По сути, они поддерживают родительский указатель на объект внешнего класса.Это правильно для реализации итератора, но вам нужно изменить то, как вы используете дженерики.Нестатические внутренние классы могут использовать параметры типа своего родительского класса.Это означает, что вы можете изменить определение итератора на:

    private final class Cursor implements Iterator<T>

    , и он будет автоматически использовать <T> с LinkedList.

  3. this.current = current;, вероятно, должно быть this.current = head;

  4. Почему hasNext звонит getNext() дважды?

Надеюсь, что поможет.

...