如何实现这个FilteringIterator?
-
IObjectTest是一个具有单个布尔测试(Object o)方法的接口
-
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 extends T> 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 extends T> 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(); }
}