时间:2010-07-24 21:56:14

标签: java collections iterator

6 个答案:

答案 0 :(得分:2)

答案 1 :(得分:2)

这是一个老问题,但是如今(2019年),我们有了JDK8 +好东西。特别是,我们有流,使此任务很简单:

public static <T> Iterator<T> flatIterator(Collection<Collection<T>> collections) {

    return collections.stream()
            .filter(Objects::nonNull)
            .flatMap(Collection::stream)
            .iterator();
}

我正在过滤null个内部集合,以防万一...


编辑:如果您还想从内部集合中过滤null个元素,只需添加一个额外的非空过滤器flatMap

return collections.stream()
        .filter(Objects::nonNull)
        .flatMap(Collection::stream)
        .filter(Objects::nonNull)
        .iterator();

答案 2 :(得分:1)

this post中,您可以看到两个实现,唯一(次要)的区别在于它需要迭代器的迭代器而不是集合的集合。

这种差异结合了以循环方式迭代元素的要求(OP在这个问题中没有请求的要求)增加了将迭代器复制到a中的开销。列表。

第一种方法是懒惰的:它只会在请求这个元素时迭代元素,我们必须支付的“价格”是代码更复杂,因为它需要处理更多的边缘情况:

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;    

public class MultiIterator<E> implements Iterator {

    List<Iterator<E>> iterators = new LinkedList<>();
    Iterator<E> current = null;

    public MultiIterator(Iterator<Iterator<E>> iterator) {
        // copy the iterators into a list
        while (iterator.hasNext()) {
            iterators.add(iterator.next());
        }
    }

    @Override
    public boolean hasNext() {
        boolean result = false;
        if (iterators.isEmpty() && (current == null || !current.hasNext())) {
            return false;
        }

        if (current == null) {
            current = iterators.remove(0);
        }

        while (!current.hasNext() && !iterators.isEmpty()) {
            current = iterators.remove(0);
        }

        if (current.hasNext()) {
            result = true;
        }
        return result;
    }

    @Override
    public E next() {
        if (current == null) {
            try {
                current = iterators.remove(0);
            } catch (IndexOutOfBoundsException e) {
                throw new NoSuchElementException();
            }
        }
        E result = current.next(); // if this method was called without checking 'hasNext' this line might raise NoSuchElementException which is fine
        iterators.add(current);
        current = iterators.remove(0);
        return result;
    }

    // test
    public static void main(String[] args) {
        List<Integer> a = new LinkedList<>();
        a.add(1);
        a.add(7);
        a.add(13);
        a.add(17);
        List<Integer> b = new LinkedList<>();
        b.add(2);
        b.add(8);
        b.add(14);
        b.add(18);
        List<Integer> c = new LinkedList<>();
        c.add(3);
        c.add(9);
        List<Integer> d = new LinkedList<>();
        d.add(4);
        d.add(10);
        d.add(15);
        List<Integer> e = new LinkedList<>();
        e.add(5);
        e.add(11);
        List<Integer> f = new LinkedList<>();
        f.add(6);
        f.add(12);
        f.add(16);
        f.add(19);
        List<Iterator<Integer>> iterators = new LinkedList<>();
        iterators.add(a.iterator());
        iterators.add(b.iterator());
        iterators.add(c.iterator());
        iterators.add(d.iterator());
        iterators.add(e.iterator());
        iterators.add(f.iterator());
        MultiIterator<Integer> it = new MultiIterator<>(iterators.iterator());
        while (it.hasNext()) {
            System.out.print(it.next() + ","); // prints: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
        }
    }
}

和第二个('贪婪'将请求顺序中所有迭代器中的所有元素复制到列表中并将迭代器返回到该列表):

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class MultiIterator<E> {

    Iterator<Iterator<E>> iterator = null;
    List<E> elements = new LinkedList<>();

    private MultiIterator(Iterator<Iterator<E>> iterator) {
        this.iterator = iterator;
    }

    private void copyElementsInOrder() {
        List<Iterator<E>> iterators = new LinkedList<>();
        // copy the iterators into a list
        while (iterator.hasNext()) {
            iterators.add(iterator.next());
        }
        // go over the list, round-robin, and grab one
        // element from each sub-iterator and add it to *elements*
        // empty sub-iterators will get dropped off the list
        while (!iterators.isEmpty()) {
            Iterator<E> subIterator = iterators.remove(0);
            if (subIterator.hasNext()) {
                elements.add(subIterator.next());
                iterators.add(subIterator);
            }
        }
    }

    public static <E> Iterator<E> iterator(Iterator<Iterator<E>> iterator) {
        MultiIterator<E> instance = new MultiIterator<>(iterator);
        instance.copyElementsInOrder();
        return instance.elements.iterator();
    }

    // test
    public static void main(String[] args) {
        List<Integer> a = new LinkedList<>();
        a.add(1);
        a.add(7);
        a.add(13);
        a.add(17);
        List<Integer> b = new LinkedList<>();
        b.add(2);
        b.add(8);
        b.add(14);
        b.add(18);
        List<Integer> c = new LinkedList<>();
        c.add(3);
        c.add(9);
        List<Integer> d = new LinkedList<>();
        d.add(4);
        d.add(10);
        d.add(15);
        List<Integer> e = new LinkedList<>();
        e.add(5);
        e.add(11);
        List<Integer> f = new LinkedList<>();
        f.add(6);
        f.add(12);
        f.add(16);
        f.add(19);
        List<Iterator<Integer>> iterators = new LinkedList<>();
        iterators.add(a.iterator());
        iterators.add(b.iterator());
        iterators.add(c.iterator());
        iterators.add(d.iterator());
        iterators.add(e.iterator());
        iterators.add(f.iterator());
        Iterator<Integer> it = MultiIterator.<Integer>iterator(iterators.iterator());
        while (it.hasNext()) {
            System.out.print(it.next() + ","); // prints: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
        }
    }
}

我提供了一个简单的'测试'代码,以显示使用MultiIterator的方法,这并不总是微不足道的(因为使用了Generics),你可以在线上看到:

Iterator<Integer> it = MultiIterator.<Integer>iterator(iterators.iterator());

答案 3 :(得分:1)

这是另一种实现方式:

import java.util.Iterator;
import java.util.NoSuchElementException;

import static java.util.Collections.emptyIterator;

public class Multiterator<E> implements Iterator<E> {
    private Iterator<Iterator<E>> root;
    private Iterator<E> current;

    public Multiterator(Iterator<Iterator<E>> root) {
        this.root = root;
        current = null;
    }

    @Override
    public boolean hasNext() {
        if (current == null || !current.hasNext()) {
            current = getNextNonNullOrEmpty(root);
        }
        return current.hasNext();
    }

    private Iterator<E> getNextNonNullOrEmpty(Iterator<Iterator<E>> root) {
        while (root.hasNext()) {
            Iterator<E> next = root.next();
            if (next != null && next.hasNext()) {
                return next;
            }
        }
        return emptyIterator();
    }

    @Override
    public E next() {
        if (current == null) {
            throw new NoSuchElementException();
        }
        return current.next();
    }
}

答案 4 :(得分:0)

答案 5 :(得分:0)

如果所有你必须使用的是java Iterator:它只有hasNext(),next()和remove(),我想你必须绕过它。

处理它,因为您将处理2D数组,即使用外部和内部循环,因为它们具有相同的“排列”但不同的数据类型。在处理过程中,您将它们转移到新的集合中。

所以也许是私人方法:

    private void convertToSingleCollection()
    {


         while("column")
         {
            //convert the "column" to an arra


           for( "Row")
           {
            //add to newCollection here
           }

          //remove the processed column from CollectionOFcollection
         } 
    }
    //call the above method in your constructor


    public iterator<T> Iterator()
    {
       newCollection.iterator();
    }

    public boolean hasNext()
    {
       return Iterator().hasNext()
    }

    public T next()
    {
       if(!hasNext())
       {
        //exception message or message
       }
       else
           //return "next"
    }

我希望这会有所帮助。我想应该有其他解决方法。