【问题标题】:using java generics properly?正确使用java泛型?
【发布时间】:2013-04-29 18:42:36
【问题描述】:

我在使用 java 泛型时遇到了问题。 当我从迭代器中使用 next() 时,它不会返回与我实例化它的类型相同的对象。所以我收到一个不兼容的类型错误。 有人可以帮忙吗?

我在编译链表类时也会收到 Xlint 警告。

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());
    }
 }

}

这是在创建列表并填充不同类型的形状后,主类中出现错误的地方。

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

【问题讨论】:

  • 您确定在代码中的任何地方都没有使用原始类型(例如纯 LinkedList 而不是 LinkedList&lt;String&gt;)吗?这可能是对您所描述内容的解释。请显示您实际调用next 的代码,错误发生的位置。
  • private Node current; 应该是private Node&lt;Type&gt; current;

标签: java generics iterator incompatibletypeerror


【解决方案1】:

Iterator is a generic interface,但您的 ListIterator 既不是通用的,也不是参数化的 Iterator。首先让ListIterator 实现Iterator&lt;Type&gt;

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

或将ListIterator 也设为通用(更复杂):

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
    }
}

【讨论】:

  • 更改迭代器后我仍然遇到同样的问题。
  • 除了没有实现 remove() 的迭代器之外,基本代码对我来说编译得很好。 ideone.com/OTYxvP
  • 如果他做后者,他也应该让ListIterator不是一个内部类
【解决方案2】:

你能发布代码来说明你是如何使用它的吗?

确保在使用 ListIterator 类时,将其泛化为 LinkedList&lt;Something&gt;.ListIterator。否则,LinkedList.ListIterator 类型的迭代器将是原始类型,而其 next() 将返回 Object

也不要参数化ListIterator。否则,它将遮蔽外部类上的类型变量。内部(非静态)类可以使用外部类的类型变量。此外,如果你这样做了,你将不得不做LinkedList&lt;Something&gt;.ListIterator&lt;Something&gt; 以使其保持一致;你甚至不能做LinkedList.ListIterator&lt;Something&gt;,因为你不能给原始类型的内部类提供泛型参数。

【讨论】:

  • 啊,谢谢你们两个人!它需要是 Iterator iter = unsorted.iterator(); 而不是 Iterator iter = unsorted.iterator();
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-26
相关资源
最近更新 更多