我正在尝试使用Iterator作为内部类来实现Collection接口。实现集合的ArrayCollection类有一个泛型数组(它是一种正确的方式来表示类成员是通用的吗?)。 a screenshot from IDE
public class ArrayCollection<T> implements Collection<T> {
private T[] m = (T[])new Object[10];
但是当我为Iterator接口实现方法next()时,我不断收到不兼容的类型错误。但是,如果创建一个ArrayIterator,非泛型类编译器不再存在数组类型转换的问题。 an error screenshot from IDE
private class ArrayIterator<T> implements Iterator<T> {
private int cursor = 0;
@Override
public boolean hasNext() {
return this.cursor >= ArrayCollection.this.size();
}
@Override
public T next() {
return ArrayCollection.this.m[cursor++];
}
}
所以我几乎没有问题:
如果我使ArrayIterator非泛型,编译器如何定义T [] m数组类型?
实现/扩展通用接口/类只是内部类可以是非泛型的吗?
答案 0 :(得分:2)
您类似地命名了类型变量,ArrayIterator<T>
的{{1}}与T
的{{1}}不同。
您可以从ArrayCollection<T>
中删除T
(因为它是非静态内部类),只需让<T>
使用父类中的ArrayIterator
:
Iterator
这将解决编译问题和您的代码。
答案 1 :(得分:1)
在第二个示例中,您正在处理两个不同的类型变量。外部类和内部类各自定义变量T
,但它们不相同。有几种方法可以解决这个问题,一种是从内部类声明中删除T:
private class ArrayIterator implements Iterator<T> {
现在您只引用外部T,而不引入单独的内部T
但是,我个人更喜欢使内部类静态,在这种情况下你不能使用外部类型的变量。在这种情况下,你要写
private static class ArrayIterator<T> implements Iterator<T> {
如果这样做,则需要将类型变量从外部类型传递到内部:
return new ArrayIterator<T>();
主要区别在于定义类型参数的类会影响同名的任何现有类型参数,从而导致出现奇怪的错误消息。
最后让我补充一点,从头开始实现Collection通常不是一个好主意。相反,您可能希望扩展AbstractCollection
或AbstractList
。这将让您专注于您的核心算法,但免费为您提供所有样板方法。