I am providing some facade classes for a third-party API and I need to wrap an iterator so that I can replace what is iterated with my own facade object.
Here's a simplified version of my facade class that wraps an API class called Item
class FacadeItem {
Item item;
FacadeItem(Item item) {
this.item = item;
}
}
The API provides an iterator of this form Iterator<Item>
I need to implement an iterator of this form Iterator<FacadeItem>
that is backed by the iterator of the API.
I considered using the ForwardingIterator from the Guava library as follows:
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());
}
}
but the Override of next()
is not permitted by the compiler because it is expecting the returned type to be Item, not FacadeItem
The Iterator
interface isn't that big, so you could just write your own delegating 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
}
and then
Iterator<FacadeItem> facadeIterator = new FacadeIterator(itemIterator);
If you're using Guava, you can use their Iterators.transform
static method to make one of these for you:
Iterator<FacadeItem> facadeIterator = Iterators.transform(itemIterator,
/* anon class of Function<Item, FacadeItem> */);
And in Java 1.8, this option becomes really easy:
Iterator<FacadeItem> facadeIterator
= Iterators.transform(itemIterator, FacadeItem::new)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With