我想要这样的东西,这就是我所做的(基于对 Lambdaj 所做的一些工作)。
主要缺陷是这Iterator
基本上会用 Iterator 的所有假定内容填充 a List
,这些内容可能在内存中非常重。
为什么我使用列表,因为有时一个Iterator
以特定顺序迭代,所以“sub- Iterators
”必须做同样的事情(这ListIterator
真的对我有帮助)。
public class IterableIterator<T> implements Iterable<T>, Iterator<T> {
//The content of the given iterator. Will be filled by its iterators.
private final List<T> iteratorContent = new ArrayList<T>();
private final Iterator<T> originalIterator;
private final Iterator<T> innerIterator;
public IterableIterator(Iterator<T> originalIterator) {
this(originalIterator, false);
}
public IterableIterator(Iterator<T> originalIterator, boolean cache) {
if (originalIterator == null) {
throw new IllegalArgumentException("Parameter can't be null");
}
this.originalIterator = originalIterator;
if (cache) {
while (originalIterator.hasNext()) {
iteratorContent.add(originalIterator.next());
}
}
innerIterator = iterator();
}
@Override
public Iterator<T> iterator() {
return new IteratorIterator();
}
@Override
public boolean hasNext() {
return innerIterator.hasNext();
}
@Override
public T next() {
return innerIterator.next();
}
@Override
public void remove() {
innerIterator.remove();
}
private class IteratorIterator implements Iterator<T> {
private ListIterator<T> innerIterator = iteratorContent.listIterator();
@Override
public boolean hasNext() {
return innerIterator.hasNext() || originalIterator.hasNext();
}
@Override
public T next() {
if (!innerIterator.hasNext() && originalIterator.hasNext()) {
T item;
synchronized (originalIterator) {
item = originalIterator.next();
iteratorContent.add(item);
}
innerIterator = iteratorContent.listIterator(innerIterator.nextIndex());
}
if (innerIterator.hasNext()) {
try {
return innerIterator.next();
} catch (ConcurrentModificationException e) {
//Quick and dirty solution if you have a concurrent modification.
//It can't happen from the outside, so you can easily suppose that another originalIterator
//from this class has been called and had added elements to the list.
//Best thing to do, reset the originalIterator to the current position.
innerIterator = iteratorContent.listIterator(innerIterator.nextIndex());
return innerIterator.next();
}
}
throw new NoSuchElementException();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
}