在java中为集合集合设计一个迭代器。迭代器应该隐藏嵌套,允许您迭代属于所有集合的所有元素,就像处理单个集合一样
发布于 2010-07-25 06:30:49
这是一个可能的实现。请注意,我没有实现remove():
public class MultiIterator <T> implements Iterator<T>{
private Iterator<? extends Collection<T>> it;
private Iterator<T> innerIt;
private T next;
private boolean hasNext = true;
public MultiIterator(Collection<? extends Collection<T>> 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
}
}发布于 2019-01-09 20:53:18
这是一个古老的问题,但现在(2019)我们有JDK8+的好东西。特别是,我们有streams,这使得这项任务变得简单:
public static <T> Iterator<T> flatIterator(Collection<Collection<T>> collections) {
return collections.stream()
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.iterator();
}我正在过滤掉null内部集合,以防万一...
EDIT:如果您还想将null元素从内部集合中过滤出来,只需在flatMap后面添加一个额外的非空过滤器
return collections.stream()
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.filter(Objects::nonNull)
.iterator();发布于 2015-11-16 10:09:40
在this post中,您可以看到两种实现,唯一(次要的)区别是它接受迭代器的迭代器,而不是集合的集合。
这种差异,再加上以循环方式迭代元素的要求(这个问题中的OP没有要求),增加了将迭代器复制到列表中的开销。
第一种方法是惰性的:它只在请求一个元素时才会迭代这个元素,我们必须付出的代价是代码更复杂,因为它需要处理更多的边缘情况:
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的方法,这并不总是微不足道的(因为使用了泛型),正如您在代码行中所看到的:
Iterator<Integer> it = MultiIterator.<Integer>iterator(iterators.iterator());https://stackoverflow.com/questions/3327077
复制相似问题