2016-09-17 82 views
0

我试图用Iterator作为内部类实现集合接口。一个实现集合的ArrayCollection类具有一个通用数组(这是说类成员是否通用的正确方法?)。 a screenshot from IDE集合和迭代器接口作为内部类的实现

public class ArrayCollection<T> implements Collection<T> { 
private T[] m = (T[])new Object[10]; 

然而,当我在一个Iterator接口实现下一个()的方法我不断收到不兼容类型的错误。但是,如果创建一个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++]; 
    } 
} 

所以,我有几个问题:

  1. 为什么编译器可以定义T []数组米型,如果我做一个ArrayIterator非通用?

  2. 是否只有内部类实现/扩展通用接口/类可以是非泛型的?

+0

你可以在这里分享代码吗? – Mureinik

+0

添加代码。还有IDE的链接截图。我的堆栈溢出评级太低,无法将图像直接添加到问题中。 – user2992672

+1

绝不添加图片,添加代码 –

回答

1

在第二个示例中,您正在处理两个不同类型的变量。外部类和内部类分别定义变量T,但它们不相同。有几种方法来解决这个问题,一个是从内部类声明中删除T:

private class ArrayIterator implements Iterator<T> { 

现在你只引用外T,而不会引入一个独立的内部牛逼

不过,我想个人更喜欢使内部类为静态,在这种情况下,您不能使用外部类型的变量。在这种情况下,你会写

private static class ArrayIterator<T> implements Iterator<T> { 

如果你这样做,你需要的类型变量从外部类型传递到内:

return new ArrayIterator<T>(); 

的主要区别是,一个类定义类型参数会隐藏任何现有的同名类型参数,这会导致出现奇怪的错误消息。

最后让我补充说,从头开始实施一个集合通常不是一个好主意。相反,您可能需要扩展AbstractCollectionAbstractList。这将让你专注于你的核心算法,但免费提供所有样板方法。

2

您的类型变量同样命名为ArrayIterator<T>ArrayCollection<T>T有不同的T

你可以只取出<T>ArrayIterator(因为它是一个非静态内部类),只是有Iterator使用T从父类:

private class ArrayIterator implements Iterator<T> { 

这将解决编译问题,然后将码。