2014-05-16 1 views
3

Je fournis des classes de facade pour une API tierce et j'ai besoin d'envelopper un itérateur afin de pouvoir remplacer ce qui est itéré par mon propre API. objet de façade.Comment placer un java.util.Iterator pour changer le type d'objet itéré

Voici une version simplifiée de ma classe de façade qui enveloppe une classe API appelée Item

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

L'API fournit un itérateur de cette forme Iterator<Item>

Je dois mettre en œuvre un itérateur de ce formulaire Iterator<FacadeItem> qui est soutenu par l'itérateur de l'API.

Je considère en utilisant la ForwardingIterator de la bibliothèque goyave comme suit:

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()); 
    } 
} 

mais la neutralisation de next() n'est pas autorisée par le compilateur parce qu'il attend le type retourné à être article, non FacadeItem

Répondre

10

L'interface Iterator est pas grand, vous pouvez donc écrire votre propre déléguant 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 
} 

puis

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

Si vous utilisez goyave, vous pouvez utiliser leur Iterators.transform méthode statique pour faire un de ces pour vous:

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

Et en Java 1.8, cette option devient vraiment facile:

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

Excellente réponse. Par souci d'exhaustivité, je mentionnerai simplement pour ceux qui pourraient en venir là plus tard que les "deux autres méthodes" que vous devez remplacer dans votre première solution sont hasNext() et remove() –

Questions connexes