是否可以在Java中合并迭代器?

Jah*_*ooq 44 java iteration iterator

是否可以在Java中合并迭代器?我有两个迭代器,我想组合/合并它们,以便我可以一次性迭代它们的元素(在同一个循环中)而不是两个步骤.那可能吗?

请注意,两个列表中的元素数量可能不同,因此两个列表上的一个循环不是解决方案.

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();
  .....
}
Run Code Online (Sandbox Code Playgroud)

And*_*ffy 50

Guava(以前的Google Collections)有Iterators.concat.

  • @youssef @Colin:链接的意图是立即转到`concat()`方法而不滚动(使用`#`哈希片段).然而,该部分未正确进行URL编码.我修复了它(当从其地址栏复制链接时,使用自动URL编码的长期Firefox). (4认同)
  • @guerda:你错了.Iterators.concat是懒惰的; 它不会缓冲列表中的元素. (2认同)

Ith*_*her 19

此外,Apache Commons Collection还有几个用于操作迭代器的类,比如IteratorChain,它包含了许多迭代器.

  • 我认为这种方法资源消耗较少,因为它不会将所有迭代器转换为ArrayList. (2认同)

Noe*_*l M 16

您可以创建自己的Iterator接口实现,迭代遍历迭代器:

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 */ }
}
Run Code Online (Sandbox Code Playgroud)

(为简洁起见,我没有在迭代器中添加泛型.)实现不是太难,但不是最简单的,你需要跟踪Iterator你当前正在迭代的内容,并且调用next()你需要迭代至于你可以通过迭代器,直到你找到一个hasNext()返回true,或者你可能会击中最后一个迭代器的末尾.

我不知道任何已经存在的实现.

更新:
我已经投票给安德鲁达菲的答案 - 无需重新发明轮子.我真的需要更深入地研究番石榴.

我为可变数量的参数添加了另一个构造函数 - 几乎脱离主题,因为这里构造类的方式并不是真正有意义的,只是它的工作原理.


Chr*_*fer 12

我有一段时间没有编写Java代码,这让我很好奇我是否仍然"得到它".

第一次尝试:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

可以,当然使用更多的集合类,而不是一个纯粹的阵列+索引计数器,但其实这感觉比其他清洁了一下.或者我现在偏向于写作大部分是C?

无论如何,你去吧.你问的答案是"是的,可能".


Tar*_*nin 8

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));
Run Code Online (Sandbox Code Playgroud)


mhs*_*ams 5

将循环移至方法并将迭代器传递给方法。

void methodX(Iterator x) {
    while (x.hasNext()) {
        ....
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

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();
    }
}
Run Code Online (Sandbox Code Playgroud)