自定义Java迭代器与类型混淆

4

我有一个通用类,它将一个对象和一个顺序捆绑在一起:

public class OrderedObject<T> {
    private int order;
    private T object;

    public OrderedObject(int order, T object) {
        this.order = order;
        this.object = object;
    }

    public int getOrder() {
        return order;
    }

    public T getObject() {
        return object;
    }
}

我开发了一个Set实现,它存储OrderedObject<T>实例并想要生成一个Iterator<T>,按照内置顺序进行枚举:

public class OrderedObjectSet<T> extends AbstractSet<T> implements Set<T> {
    Set<OrderedObject<T>> s = new HashSet<OrderedObject<T>>();

    public boolean add(int order, T object) {
        return s.add(new OrderedObject<T>(order, object));
    }

    public Iterator<T> iterator() {
        return new OrderedObjectSetIterator<T>();
    }

    public int size() {
        return s.size();
    }

    private class OrderedObjectSetIterator<T> implements Iterator<T> {
        private int index;

        public boolean hasNext() {
            return index < s.size();
        }

        public T next() {
            T object = null;

            for (Iterator<OrderedObject<T>> it = s.iterator(); it.hasNext(); ) {
                OrderedObject<T> o = it.next();
                if (o.getOrder() == index) {
                    object = o.getObject();
                }
            }

            index++;
            return object;
        }

        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
}

后面的这个类无法编译,因为在Iterator初始化时存在类型混淆。

for (Iterator<OrderedObject<T>> it = s.iterator(); it.hasNext(); ) {

我忽略了什么?


3
你知道 TreeSet,对吗? - Michael Myers
嗯...将一个公共的无参构造函数添加到OrderedObjectSetIterator<T>中是否解决了问题?当我看不到任何显式构造函数时,我会感到怀疑。 - Jason S
1
而且不需要编写所有可能存在错误的代码。 - Michael Myers
这不应该有任何影响,因为a)构造函数与发生错误的行无关,b)默认的无参构造函数由编译器自动添加。 - Michael Myers
使用自定义比较器的TreeSet是一种更加优雅的方法。谢谢。 - Bart Strubbe
显示剩余2条评论
1个回答

5
混淆的原因是内部类OrderedObjectSetIterator引入了一个与外部类相同的通用类型(T)。 Eclipse IDE会显示一个警告:
The type parameter T is hiding the type T   

所以我猜你不需要引入另一个参数类型,只需使用与外部类定义相同的参数类型。

基本上,内部类将被定义为:

private class OrderedObjectSetIterator implements Iterator<T> {
....

而迭代器方法如下:

public Iterator<T> iterator() {
    return new OrderedObjectSetIterator();
}

这就是问题所在。 我不需要另一种参数类型。 谢谢。 问题已解决。我觉得建议的TreeSet方法是更优雅的解决方案。尽管如此,我很高兴通过尝试自己编写的Set来获得关于泛型的见解。Bart - Bart Strubbe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接