如何包装java.util.Iterator以更改正在迭代的对象的类型

时间:2014-05-16 00:17:35

标签: java collections guava iterator-facade

我为第三方API提供了一些外观类,我需要包装一个迭代器,以便我可以替换用我自己的外观对象迭代的东西。

这是我的facade类的简化版本,它包含一个名为 Item

的API类
class FacadeItem {
    Item item;
    FacadeItem(Item item) {
        this.item = item;
    }
}

API提供了此格式Iterator<Item>

的迭代器

我需要实现一个由API的迭代器支持的这种形式Iterator<FacadeItem>的迭代器。

我考虑使用Guava库中的ForwardingIterator,如下所示:

class FacadeItemIterator<FacadeItem> extends ForwardingIterator<Item> {

    final Iterator<Item> delegate; // backing iterator

    FacadeItemIterator(Iterator<Item> delegate) {
        this.delegate = delegate;
    }

    @Override protected Iterator<Item> delegate() {
        return delegate;
    }

    @Override
    public FacadeItem next() {
        return new FacadeItem(super.next());
    }
}

但编译器不允许覆盖next(),因为它期望返回的类型为 Item ,而不是 FacadeItem

1 个答案:

答案 0 :(得分:11)

Iterator接口不是那么大,所以你可以编写自己的委托迭代器:

class FacadeIterator implements Iterator<FacadeItem> {
    private final Iterator<Item> delegate; // set in ctor

    @Override
    public FacadeItem next() {
        return new FacadeItem(delegate.next());
    }

    // the other two methods just delegate straight
}

然后

Iterator<FacadeItem> facadeIterator = new FacadeIterator(itemIterator);

如果您正在使用Guava,您可以使用他们的Iterators.transform静态方法为您制作其中一种:

Iterator<FacadeItem> facadeIterator = Iterators.transform(itemIterator,
    /* anon class of Function<Item, FacadeItem> */);

在Java 1.8中,这个选项变得非常简单:

Iterator<FacadeItem> facadeIterator
    = Iterators.transform(itemIterator, FacadeItem::new)