Не удается преобразовать из узла <E>в узел <E>? - PullRequest
1 голос
/ 22 августа 2011

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

Type mismatch: cannot convert from type DoublyLinkedList.Node<E> to DoublyLinkedList.Node<E>

Код:

import java.util.Iterator;
    import java.util.ListIterator;
    import java.util.NoSuchElementException;


public class DoublyLinkedList<E extends Comparable<E>> implements Iterable<E>{

 private int size = 0;
 private Node<E> head;
 private Node<E> tail;

/** Returns a list iterator object for the list at 
 * the specified index
 */

 public DoublyLinkedList(){


}



private static class Node<E> {

    Node<E> next = null;
    Node<E> prev = null;
    E data;

    public Node(E dataItem){
        data = dataItem;
    }

    public Node(E dataItem, Node<E> previous, Node<E> nextNode){
        this(dataItem);
        prev = previous;
        next = nextNode;
    }

}


private class MyListIter<E> implements ListIterator<E>{

    private Node<E> lastReturned; // a link reference to the last item that was returned
    private Node<E> nextItem; // a link reference to the next item in the list
    /** The index of the current position */ 
    private int index = 0;

    public MyListIter(int pos){
        if (pos < 0 || pos > size)
            throw new IndexOutOfBoundsException("Invalid index: " + index);
        lastReturned = null;
        if (pos == size){
            index = size;
            nextItem = null;
        } else { // otherwise we will start at the beginning of the list, and loop until the position in the argument
            nextItem = head; // ERROR
            for (index = 0; index < pos; index++){
                nextItem = nextItem.next; // next item will always reference the list node that is called by the next method
            }

        }
    }

    @Override
    public void add(E element) {
        if (head == null){
            Node<E> newNode = new Node<E>(element);
            head = newNode; // ERROR
            tail = head;
        }


    }
    @Override
    public boolean hasNext() {
        return nextItem != null; // just checks to make sure there is a node following the current node
    }
    @Override
    public boolean hasPrevious() {
        return (nextItem == null && size != 0) || nextItem.prev != null;
    }
    @Override
    public E next() {
        if (!hasNext())
            throw new NoSuchElementException("There is no node at that location");
        lastReturned = nextItem;
        nextItem = nextItem.next;
        index++;
        return lastReturned.data;
    }
    @Override
    public int nextIndex() {
        // TODO Auto-generated method stub
        return 0;
    }
    @Override
    public E previous() {
        if (!hasPrevious())
            throw new NoSuchElementException();
        if (nextItem == null) // the iterator is at the end of the list
            nextItem = tail; // therefore, the nextItem is at the tail, so the previous is the tail. ERROR HERE TOO
        else
            nextItem = nextItem.prev;
        lastReturned = nextItem;
        index--;
        return lastReturned.data;
    }
    @Override
    public int previousIndex() {
        // TODO Auto-generated method stub
        return 0;
    }
    @Override
    public void remove() {
        // TODO Auto-generated method stub

    }
    @Override
    public void set(E arg0) {
        // TODO Auto-generated method stub

    }



}


@Override
public Iterator<E> iterator() {
    // TODO Auto-generated method stub
    return null;
}


}

Я прокомментировал, где именно я получаю ошибку в 3 разных местах. Если вы можете предоставить какие-либо отзывы, я был бы признателен. Моя книга не обращается к этому, и я искал вокруг и не могу, кажется, получить ответ, который я ищу.

Ответы [ 3 ]

5 голосов
/ 22 августа 2011

Вы объявили два разных универсальных типа: E (для Node) и E extends Comparable<E> (для DoublyLinkedList).

Основная проблема здесь, вероятно, MyListIter, чтонестатический внутренний класс и, как таковой, автоматически наследует определение DoublyLinkedList E.Поскольку он наследует определение E, вы должны просто объявить его как

private class MyListIter implements ListIterator<E>

, но вы сделали его MyListIter<E>, который переопределяет E на нечто иное, чем Eчто DoublyLinkedList пользователей (неявные E extends Object против E extends Comparable<E>).

I считают, Node должны работать как есть, поскольку это вложенный класс (с static ключевое слово) и не наследует определение E от DoublyLinkedList.Однако, здесь, вероятно, имеет смысл объявить его как нестатический внутренний класс DoublyLinkedList (private class Node), такой же, как MyListIter.

Кроме того, вы, вероятно, должны разрешить Eбыть типом, который является подтипом некоторого типа, который реализует Comparable, объявив его как E extends Comparable<? super E>.

3 голосов
/ 22 августа 2011

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

private class Node {

Node next = null;
Node prev = null;
E data;

...

РЕДАКТИРОВАТЬ: , как отмечает ColinD, MyListIter также не следует повторно декларировать E как параметр типа.Изменение этого с помощью Node должно исправить проблему.

1 голос
/ 22 августа 2011

ColinD прав (+1).

Чтобы понять, что происходит, представьте, что вы не используете один и тот же параметр формального типа 3 раза, но E для DoublyLinkedList, F для Node и G для MyListIter. Тогда сообщение об ошибке скажет Type mismatch: cannot convert from type DoublyLinkedList.Node<E> to DoublyLinkedList.Node<G>. Решение - это то, что предложил ColinD. Если вы хотите, вы можете оставить Node<F> статичным, с исправлением все экземпляры будут иметь один и тот же фактический параметр типа.

...