IObjectTest是一个带有的接口 单布尔测试(Object o)方法
FilteringIterator是Iterator的一个实现 用另一个迭代器初始化 和一个IObjectTest实例:new FilteringIterator(myIterator, MYTEST)。你的FilteringIterator会 然后允许迭代 'myIterator',但跳过任何 没有通过的物体 'myTest'测试。
由于“hasNext”操作实际上涉及重复移动底层迭代器 直到下一个匹配的项目。问题是如何将it迭代器移回迭代器,因为hasNext不应该移动底层迭代器。
答案 0 :(得分:10)
如果您想自己动手,可以使用类似于我在下面编写的代码。但是,我建议您使用Guava的Iterators.filter(Iterator, Predicate)
public class FilteredIterator<T> implements Iterator<T> {
private Iterator<? extends T> iterator;
private Filter<T> 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<T> 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<T> {
/**
* 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);
}
答案 1 :(得分:5)
您需要使迭代器具有状态。缓存从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
}
答案 2 :(得分:4)
如果这是作业,这对你没有帮助,但如果没有:Guava Library具有你以后的确切功能
Iterators.filter(Iterator, Predicate)
(您可以查看how they did it获取灵感)
答案 3 :(得分:0)
我的版本怎么样?与前面的例子相比,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();
}
}