Is it possible to merge iterators in Java?

Viewed 39266

Is it possible to merge iterators in Java? I have two iterators and I want to combine/merge them so that I could iterate though their elements in one go (in same loop) rather than two steps. Is that possible?

Note that the number of elements in the two lists can be different therefore one loop over both lists is not the 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();
  .....
}
14 Answers

Starting with Java 8 and later this can be done without external dependencies using Stream API. This also allows concatenation of iterator with other types of streams.

Streams.concat(StreamSupport.stream(<iter1>, false), StreamSupport.stream(<iter2>, false));

In the Apache Commons Collections there is public static <E> Iterator<E> org.apache.commons.collections4.IteratorUtils.chainedIterator(Collection<Iterator<? extends E>> iterators) that says

Gets an iterator that iterates through a collections of Iterators one after another.

which should be what you want.

import java.util.Arrays;
import java.util.Iterator;

import org.apache.commons.collections4.IteratorUtils;
//also works: import org.apache.commons.collections.IteratorUtils;

class Scratch {
    public static void main( String[] args ) {
        final Iterator<String> combinedIterator = IteratorUtils.chainedIterator(
                Arrays.asList( "a", "b", "c" ).iterator(),
                Arrays.asList( "1", "2", "3" ).iterator()
            );
        while( combinedIterator.hasNext() ){
            System.out.println( combinedIterator.next() );
        }
        // "abc123" will have been printed out
    }
}
Related