Is it possible to merge iterators in Java?

后端 未结 14 1631
自闭症患者
自闭症患者 2020-11-30 08:14

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) rathe

相关标签:
14条回答
  • 2020-11-30 08:50
    public class IteratorJoin<T> implements Iterator<T> {
        private final Iterator<T> first, next;
    
        public IteratorJoin(Iterator<T> first, Iterator<T> next) {
            this.first = first;
            this.next = next;
        }
    
        @Override
        public boolean hasNext() {
            return first.hasNext() || next.hasNext();
        }
    
        @Override
        public T next() {
            if (first.hasNext())
                return first.next();
            return next.next();
        }
    }
    
    0 讨论(0)
  • 2020-11-30 08:54

    I haven't written Java code in a while, and this got me curious to whether I've still "got it".

    First try:

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

    You could of course use more Collection classes rather than a pure array + index counter, but this actually feels a bit cleaner than the alternative. Or am I just biased from writing mostly C these days?

    Anyway, there you go. The answer to you question is "yes, probably".

    0 讨论(0)
  • 2020-11-30 08:59

    I would refactor the original design from:

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

    To something like:

    Iterator<User> users = userService.getUsersInGroup(group.getId(), User.PRIMARY, User.SECONDARY, ...);
    
    0 讨论(0)
  • 2020-11-30 09:00

    You can try ConcatIterator from Cactoos:

    Iterator<String> names = new ConcatIterator<>(
      Arrays.asList("Sarah", "Mary").iterator(),
      Arrays.asList("Jeff", "Johnny").iterator(),
    );
    

    Also check ConcatIterable, which concatenates Iterables.

    0 讨论(0)
  • 2020-11-30 09:01

    every Iterator object holds own memory location (adress), so you can't simply "merge" them. except if you extend iterator class and write your own implementation there.

    If you are dealing with the same number of objects in both iterators an alternative solution would be to process two iterators in one loop like this :

       while (iterator1.hasNext() && iterator2.hasNext()) {
          // code
        }
    
    0 讨论(0)
  • 2020-11-30 09:05

    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
        }
    }
    
    0 讨论(0)
提交回复
热议问题