53 votes

Est-il possible de fusionner des itérateurs en Java?

Est-il possible de fusionner des itérateurs en Java? J'ai deux itérateurs et je veux les combiner / fusionner afin de pouvoir itérer à travers leurs éléments en une seule fois (dans la même boucle) plutôt qu'en deux étapes. Est-ce possible?

Notez que le nombre d'éléments dans les deux listes peut être différent, donc une boucle sur les deux listes n'est pas la solution.

 Iterator<User> pUsers = userService.getPrimaryUsersInGroup(group.getId());
Iterator<User> sUsers = userService.getSecondaryUsersInGroup(group.getId());

while(pUsers.hasNext()) {
  User user = pUsers.next();
  .....
}

while(sUsers.hasNext()) {
  User user = sUsers.next();
  .....
}
 

53voto

Andrew Duffy Points 3574

Goyave (anciennement Google Collections) a Iterators.concat .

21voto

Ither Points 1283

La collection Apache Commons possède également plusieurs classes pour manipuler les itérateurs, comme IteratorChain , qui encapsule un certain nombre d'itérateurs.

19voto

Noel M Points 6263

Vous pouvez créer votre propre mise en œuvre de l' Iterator interface qui effectue une itération sur les itérateurs:

public class IteratorOfIterators implements Iterator {
    private final List<Iterator> iterators;

    public IteratorOfIterators(List<Iterator> iterators) {
        this.iterators = iterators;
    }

    public IteratorOfIterators(Iterator... iterators) {
        this.iterators = Arrays.asList(iterators);
    }


    public boolean hasNext() { /* implementation */ }

    public Object next() { /* implementation */ }

    public void remove() { /* implementation */ }
}

(Je n'ai pas ajouté les génériques de l'Itérateur pour des raisons de concision.) La mise en œuvre n'est pas trop dur, mais n'est pas le plus trivial, vous avez besoin de garder une trace de ce qui Iterator vous êtes actuellement à parcourir, et en appelant next() vous aurez besoin pour effectuer une itération aussi loin que vous pouvez à travers les itérateurs jusqu'à ce que vous trouver un hasNext() qui renvoie true, ou vous pouvez frapper la fin de la dernière itérateur.

Je ne suis pas au courant de toute mise en œuvre qui existe déjà pour cela.

Mise à jour:
J'ai jusqu'-voté Andrew Duffy réponse - pas besoin de ré-inventer la roue. J'ai vraiment besoin de regarder dans la Goyave plus en profondeur.

J'ai ajouté un autre constructeur pour un nombre variable d'arguments - presque arriver hors sujet, de la façon dont la classe est construit ici n'est pas vraiment d'intérêt, tout le concept de la façon dont il fonctionne.

14voto

Christoffer Points 6518

Je n'ai pas écrit de code Java depuis un moment, ce qui m'a rendu curieux de savoir si je l'avais toujours "compris".

Premier essai:

 import java.util.Iterator;
import java.util.Arrays; /* For sample code */

public class IteratorIterator<T> implements Iterator<T> {
    private final Iterator<T> is[];
    private int current;

    public IteratorIterator(Iterator<T>... iterators)
    {
            is = iterators;
            current = 0;
    }

    public boolean hasNext() {
            while ( current < is.length && !is[current].hasNext() )
                    current++;

            return current < is.length;
    }

    public T next() {
            while ( current < is.length && !is[current].hasNext() )
                    current++;

            return is[current].next();
    }

    public void remove() { /* not implemented */ }

    /* Sample use */
    public static void main(String... args)
    {
            Iterator<Integer> a = Arrays.asList(1,2,3,4).iterator();
            Iterator<Integer> b = Arrays.asList(10,11,12).iterator();
            Iterator<Integer> c = Arrays.asList(99, 98, 97).iterator();

            Iterator<Integer> ii = new IteratorIterator<Integer>(a,b,c);

            while ( ii.hasNext() )
                    System.out.println(ii.next());
    }
}
 

Vous pouvez bien sûr utiliser plus de classes Collection plutôt qu'un pur tableau + compteur d'index, mais cela semble en fait un peu plus propre que l'alternative. Ou suis-je simplement biaisé d'écrire principalement C ces jours-ci?

Quoi qu'il en soit, voilà. La réponse à votre question est "oui, probablement".

5voto

mhshams Points 3839

déplacez votre boucle vers une méthode et passez l'itérateur à la méthode.

 void methodX(Iteartor x) {
    while (x.hasNext()) {
        ....
    }
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X