Search code examples
javagenericsiteratorincompatibletypeerror

using java generics properly?


Im having problems with java generics. When i use next() from the iterator it doesn't return an object of the same type i instantiated it with. So i recieve an incompatible types error. Can anyone help?

I also recieve an Xlint warning when i compile the linked list class.

public class LinkedList<Type>
{

private Node<Type> sentinel = new Node<Type>();
private Node<Type> current;
private int modCount;

public LinkedList()
{
    // initialise instance variables
    sentinel.setNext(sentinel);
    sentinel.setPrev(sentinel);
    modCount = 0;
}
public void prepend(Type newData)
{
   Node<Type> newN = new Node<Type>(newData);
   Node<Type> temp;
   temp = sentinel.getPrev();
   sentinel.setPrev(newN);
   temp.setNext(newN);
   newN.setPrev(temp);
   newN.setNext(sentinel);           
   modCount++;
}


private class ListIterator implements Iterator
{
    private int curPos, expectedCount;
    private Node<Type> itNode;
    private ListIterator()
    {
        curPos =0;
        expectedCount = modCount;
        itNode = sentinel;
    }

    public boolean hasNext()
    {
        return (curPos < expectedCount);
    }

    public Type next()
    {
        if (modCount != expectedCount)
            throw new ConcurrentModificationException("Cannot mutate in context of iterator");
        if (!hasNext())
            throw new NoSuchElementException("There are no more elements");
        itNode = itNode.getNext();
        curPos++;
        current = itNode;
        return (itNode.getData());
    }
 }

}

Here is where the error occurs in the main class after the list is created and filled with different types of shapes.

shape test;
Iterator iter = unsorted.iterator();
test = iter.next();

Solution

  • Iterator is a generic interface, but your ListIterator is neither generic nor parameterizes Iterator. Start by making ListIterator implement Iterator<Type>:

    private class ListIterator implements Iterator<Type> {
        // the rest should be fine
    }
    

    or making ListIterator generic as well (more complicated):

    private class ListIterator<T> implements Iterator<T>
    {
        private int curPos, expectedCount;
        private Node<T> itNode;
        private ListIterator()
        {
            curPos = 0;
            expectedCount = modCount;
            itNode = sentinel;
        }
    
        public boolean hasNext()
        {
            return (curPos < expectedCount);
        }
    
        public T next()
        {
            // snip
        }
    }