如何实现这个FilteringIterator?

  1. IObjectTest是一个具有单个布尔测试(Object o)方法的接口

  2. FilteringIterator是Iterator的一个实现,它用另一个Iterator和一个IObjectTest实例初始化:new FilteringIterator(myIterator,myTest)。 然后,您的FilteringIterator将允许迭代’myIterator’,但跳过任何未通过’myTest’测试的对象。

由于“hasNext”操作实际上涉及重复移动底层迭代器,直到到达下一个匹配项。 问题是如何将it迭代器移回迭代器,因为hasNext不应该移动底层迭代器。

你需要让你的迭代器有状态。 缓存从hasNext检索的最后一个值,并使用next方法中的值(如果存在)。

 private boolean hasCached; private T cached; public boolean hasNext() { if ( hasCached ) return true; //iterate until you find one and set hasCached and cached } public T next() { if ( hasCached ) { hasCached = false; return cached; } //iterate until next matches } 

如果你想自己做,你可以使用类似于我在下面写的代码。 但是,我建议您使用Guava的Iterators.filter(Iterator,Predicate)

 public class FilteredIterator implements Iterator { private Iterator iterator; private Filter filter; private T nextElement; private boolean hasNext; /** * Creates a new FilteredIterator using wrapping the iterator and returning only elements matching the filter. * * @param iterator * the iterator to wrap * @param filter * elements must match this filter to be returned */ public FilteredIterator(Iterator iterator, Filter filter) { this.iterator = iterator; this.filter = filter; nextMatch(); } @Override public boolean hasNext() { return hasNext; } @Override public T next() { if (!hasNext) { throw new NoSuchElementException(); } return nextMatch(); } private T nextMatch() { T oldMatch = nextElement; while (iterator.hasNext()) { T o = iterator.next(); if (filter.matches(o)) { hasNext = true; nextElement = o; return oldMatch; } } hasNext = false; return oldMatch; } @Override public void remove() { throw new UnsupportedOperationException(); } } public interface Filter { /** * Determines whether elements should be filtered or not. * * @param element the element to be matched against the filter * @return {@code true} if the element matches the filter, otherwise {@code false} */ public boolean matches(T element); } 

如果这是家庭作业,这对你没有帮助,但如果没有: 番石榴图书馆拥有你所追求的确切function

Iterators.filter(Iterator, Predicate)

(你可能会看看他们是如何为灵感而做的)

我的版本怎么样? 与前面的例子相比,next()方法可能有点容易理解。

 public class PredicateIterator implements Iterator { private Iterator iterator; private Predicate predicate; private Object cached; private boolean hasNextCached; private boolean hasNext; public PredicateIterator(Iterator iterator, Predicate predicate) { this.iterator = iterator; this.predicate = predicate; } @Override public boolean hasNext() { if (hasNextCached) { return hasNext; } else { return findNextMatch(); } } private boolean findNextMatch() { boolean match = false; while(!match && iterator.hasNext()) { cached = iterator.next(); match = predicate.test(cached); } hasNextCached = true; hasNext = match; return match; } @Override public Object next() { if (hasNext()) { hasNextCached = false; return cached; } else { throw new NoSuchElementException(); } } @Override public void remove() { iterator.remove(); } 

}