访谈:为集合集合设计迭代器

为java中的集合集合设计迭代器。 迭代器应隐藏嵌套,允许您迭代属于所有集合的所有元素,就像使用单个集合一样

这是一个可能的实现。 请注意,我离开了remove()未实现:

public class MultiIterator  implements Iterator{ private Iterator> it; private Iterator innerIt; private T next; private boolean hasNext = true; public MultiIterator(Collection> collections) { it = collections.iterator(); prepareNext(); } private void prepareNext() { do { if (innerIt == null || !innerIt.hasNext()) { if (!it.hasNext()) { hasNext = false; return; } else innerIt = it.next().iterator(); } } while (!innerIt.hasNext()); next = innerIt.next(); } @Override public boolean hasNext() { return hasNext; } @Override public T next() { if (!hasNext) throw new NoSuchElementException(); T res = next; prepareNext(); return res; } @Override public void remove() { //TODO } } 

在这篇文章中你可以看到两个实现,唯一(次要)的区别是它需要迭代器的迭代器而不是集合的集合。

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

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

 import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.NoSuchElementException; public class MultiIterator implements Iterator { List> iterators = new LinkedList<>(); Iterator current = null; public MultiIterator(Iterator> 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 a = new LinkedList<>(); a.add(1); a.add(7); a.add(13); a.add(17); List b = new LinkedList<>(); b.add(2); b.add(8); b.add(14); b.add(18); List c = new LinkedList<>(); c.add(3); c.add(9); List d = new LinkedList<>(); d.add(4); d.add(10); d.add(15); List e = new LinkedList<>(); e.add(5); e.add(11); List f = new LinkedList<>(); f.add(6); f.add(12); f.add(16); f.add(19); List> 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 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 { Iterator> iterator = null; List elements = new LinkedList<>(); private MultiIterator(Iterator> iterator) { this.iterator = iterator; } private void copyElementsInOrder() { List> 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 subIterator = iterators.remove(0); if (subIterator.hasNext()) { elements.add(subIterator.next()); iterators.add(subIterator); } } } public static  Iterator iterator(Iterator> iterator) { MultiIterator instance = new MultiIterator<>(iterator); instance.copyElementsInOrder(); return instance.elements.iterator(); } // test public static void main(String[] args) { List a = new LinkedList<>(); a.add(1); a.add(7); a.add(13); a.add(17); List b = new LinkedList<>(); b.add(2); b.add(8); b.add(14); b.add(18); List c = new LinkedList<>(); c.add(3); c.add(9); List d = new LinkedList<>(); d.add(4); d.add(10); d.add(15); List e = new LinkedList<>(); e.add(5); e.add(11); List f = new LinkedList<>(); f.add(6); f.add(12); f.add(16); f.add(19); List> 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 it = MultiIterator.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 it = MultiIterator.iterator(iterators.iterator()); 

首先,看一下java.util.LinkedList中迭代器的实现

http://www.docjar.com/html/api/java/util/LinkedList.java.html

从那里你的任务很简单,只需实现一个迭代器,它考虑到迭代集合的事实。

问候。

如果所有你必须使用的是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 Iterator() { newCollection.iterator(); } public boolean hasNext() { return Iterator().hasNext() } public T next() { if(!hasNext()) { //exception message or message } else //return "next" } 

结束

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