gpt4 book ai didi

java - 为什么我们不能为 Iterator 返回 ArrayList.iterator() ?

转载 作者:太空宇宙 更新时间:2023-11-04 06:43:51 27 4
gpt4 key购买 nike

我有一个返回 Iterator<IFoo> 的方法。在该方法中,如果我尝试返回 someArrayList类型 ArrayList<Foo> ,我收到编译错误: Type mismatch: cannot convert from Iterator<Foo> to Iterator<IFoo>

这是类型层次结构:

Interface:IFoo
--Class: Foo (Implements IFoo)

而且,这是我的方法:

public Iterator<IFoo> iterator() {  
return someArrayList.iterator();
}

我的问题是,当该方法希望我返回 Iterator<IFoo> 类型的内容时,为什么我们不能返回 someArrayList类型 ArrayList<Foo>因为 Foo 实现了 IFoo

2014 年 6 月 20 日星期五上午 8:38(世界标准时间)更新

有问题的方法public Iterator<IFoo> iterator()无法修改,因为我正在实现一个接口(interface)。

我之前就应该提到这一点。抱歉。

最佳答案

离开你最近的编辑,你说你不能修改方法签名(这真的太糟糕了,因为更灵活的签名可以避免这种情况......):

一种解决方案是创建一个具有正确类型的新List,并使用其中的迭代器。这是可行的,因为列表的各种构造函数在它们接受的类型上要灵活得多,并且将采用子类型。主要缺点是,这将生成原始 ArrayList 的浅拷贝,从而占用额外的空间(尽管不会太多,除非您正在处理非常大的列表)。这基本上是您以更紧凑的形式发布的答案。

public Iterator<IFoo> iterator() {  
return new ArrayList<IFoo>(someArrayList).iterator();
}

您必须在此处显式指定类型参数,否则类型将被推断为 Foo,这只会让您回到原来的位置。

或者,如果 new ArrayList() 调用所需的额外空间不吸引人,您可以编写一个 Iterator 的匿名子类,它只是充当包装器(我认为我的语法是正确的;可能犯了一两个小错误,但这些应该很容易修复)。它需要更多的编写,但对内存的使用更精简,这可能是可取的:

public Iterator<IFoo> iterator() {
return new Iterator<IFoo>() {
private final Iterator<? extends IFoo> iterator = someArrayList.iterator();

@Override
public boolean hasNext() {
return iterator.hasNext();
}

@Override
public Number next() {
return iterator.next();
}

@Override
public void remove() {
iterator.remove();
}
};
}
<小时/>

需要注意的一件重要事情是这些解决方案并不完全相同。

您的解决方案和我的第一个解决方案返回的迭代器在与原始列表不同的列表上运行。这个不同的列表是浅拷贝,因此您将从 hasNext()next() 获得相同的结果。但是,如果您调用 remove(),您的原始列表将不受影响,只有副本会发生更改。

匿名子类将在您的原始列表上执行其所有操作,就像您的原始解决方案一开始就有效一样。

关于java - 为什么我们不能为 Iterator<IFoo> 返回 ArrayList<Foo>.iterator() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24322096/

27 4 0