Question

Personnellement, j’estime que la gamme de fonctionnalités fournies par java.util.Iterator est assez pathétique. Au minimum, j'aimerais avoir des méthodes telles que:

  • peek () retourne l'élément suivant sans déplacer l'itérateur
  • previous () renvoie l'élément précédent

Bien qu'il y ait beaucoup d'autres possibilités telles que first () et last ().

Est-ce que quelqu'un sait si un tel itérateur tiers existe? Il devrait probablement être implémenté en tant que décorateur de java.util.Iterator afin de pouvoir fonctionner avec les collections java existantes. Idéalement, il devrait être & "; Générique au courant &";

.

Merci d'avance, Don

Était-ce utile?

Autres conseils

Vous pouvez obtenir previous() facilement en utilisant simplement un java.util.ListIterator.

Peek à ce stade est facilement implémenté en faisant un

public <T> T peek(ListIterator<T> iter) throws NoSuchElementException {
    T obj = iter.next();
    iter.previous();
    return obj;
}

Malheureusement, il sera plus facile de l’utiliser comme méthode d’utilité, car chaque classe de la collection implémente ses propres itérateurs. Faire un wrapper pour avoir une méthode de coup d'oeil sur chaque collection sur une interface telle que MyListIterator serait beaucoup de travail.

Je pense que la raison pour laquelle elles ne sont pas implémentées est qu’elles ne sont pas triviales pour certaines collections et auraient un impact important sur les performances. Je pense que ce serait assez simple pour vous de faire ce travail pour les collections qui vous intéressent.

Je n’apprécie pas non plus le fait que les itérateurs Java n’ont aucun moyen d’obtenir la valeur actuelle sans la déplacer (vous ne pouvez donc pas écrire facilement le code qui se branche en fonction de la valeur, en passant simplement l’itérateur - vous devez passer la valeur que vous avez maintenant aussi).

Il y a une bonne raison pour que les opérateurs génériques n'implémentent pas ces fonctionnalités: elles n'existent pas pour tous les conteneurs. L'exemple typique est un conteneur représentant une entrée de données externe, comme un fichier vu comme un flux. Chaque fois que vous lisez une valeur, vous la consommez et déplacez le pointeur vers l'avant, que vous le vouliez ou non. Si vous imposez ces contraintes aux itérateurs génériques, vous perdez alors la généricité des itérateurs.

Si vous souhaitez une méthode previous, comme suggéré, utilisez la ListIterator<>, qui est ensuite restreinte aux conteneurs se comportant comme des listes.

Une chose que je voudrais examiner est la mise en œuvre de Seq dans clojure

http://clojure.org/sequences

L'implémentation des classes de base est en Java et le source complet est disponible. Les Seq sont des décorateurs sur les itérateurs java (prennent et implémentent des interfaces d'itérateur java) - mais ils fournissent également leur propre interface qui peut être plus que ce que vous voulez - ou au moins un point de départ.

Comme suggéré par ykaganovich, vous pouvez consulter le google-collections . des trucs. Certaines choses que vous souhaitez, telles que furtivement . En outre, comme d'autres l'ont mentionné, la mise en œuvre de toutes ces choses pour toutes les collections peut être dangereuse du point de vue de la possibilité ou de la performance.

public class Iterazor<T> {
  private Iterator<T> it;
  public T top;
  public Iterazor(Collection<T> co) {
    this.it = co.iterator(); 
    top = it.hasNext()? it.next(): null; 
  }
  public void advance() { 
    top = it.hasNext()? it.next(): null; 
  }
}

// usage

for(Iterazor<MyObject> iz = new Iterazor<MyObject>(MyCollection); 
    iz.top!=null; iz.advance())
  iz.top.doStuff();
}

J'ai vu une personne liée à Google Collections, mais personne n'a indiqué que la méthode que vous recherchez s'appelle Iterators.peekingIterator ().

Néanmoins, il serait préférable que vous utilisiez simplement un ListIterator.

Je n'ai jamais rencontré de problème pour lequel j'ai eu besoin d'un coup d'oeil (); Iterator a très bien fonctionné pour moi. Je suis curieux de savoir comment vous utilisez des itérateurs qui, à votre avis, nécessitent cette fonctionnalité supplémentaire.

Il semble que vous feriez mieux d'utiliser une pile.

Les collections Java ont été écrites pour fournir un ensemble minimal de fonctionnalités utiles. C’est une très bonne approche pour le code qui doit être implémenté par quiconque implémentant Java. Faire grincer une interface avec des fonctionnalités qui pourraient être utiles peut entraîner une augmentation considérable du volume de code, avec des améliorations remarquées par quelques-uns seulement. Si peek () et previous () faisaient partie de l'itérateur standard, cela signifie que toute personne écrivant un nouveau type de Collection doit la mettre en œuvre, que cela soit raisonnable ou non.

Les itérateurs sont également conçus pour travailler sur des choses que physiquement ne peut pas revenir en arrière, rendant impossible peek () et previous () tous les deux.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top