java 如何实现这个 FilteringIterator?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5474893/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to implement this FilteringIterator?
提问by Leon
IObjectTest is a interface with a single boolean test(Object o) method
FilteringIterator is an implementation of Iterator which is initialized with another Iterator and an IObjectTest instance: new FilteringIterator(myIterator, myTest). Your FilteringIterator will then allow iteration over 'myIterator', but skipping any objects which don't pass the 'myTest' test.
IObjectTest 是一个带有单个布尔 test(Object o) 方法的接口
FilteringIterator 是 Iterator 的一个实现,它用另一个 Iterator 和一个 IObjectTest 实例初始化:new FilteringIterator(myIterator, myTest)。然后,您的 FilteringIterator 将允许对“myIterator”进行迭代,但会跳过任何未通过“myTest”测试的对象。
Since the "hasNext" operation actually involve repeatly moving the underlying iterator untill reach the next matching item. The question is how can it move it iterator back since hasNext is not supposed to move the underlying iterator.
由于“hasNext”操作实际上涉及重复移动底层迭代器,直到到达下一个匹配项。问题是它如何将迭代器移回,因为 hasNext 不应该移动底层迭代器。
采纳答案by Mark Peters
You would need to make your iterator stateful. Cache the last value you retrieved from hasNext
and use that from the next
method, if it exists.
您需要使迭代器有状态。缓存您从中检索到的最后一个值,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
}
回答by Roel Spilker
If you want to do it yourself, you can use code similar to what I've written below. However, I do recommend you use Guava's Iterators.filter(Iterator, Predicate)
如果你想自己做,你可以使用类似于我在下面写的代码。但是,我建议您使用 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);
}
回答by Sean Patrick Floyd
If this is homework, this won't help you, but if not: the Guava Libraryhas the exact functionality you are after
如果这是家庭作业,这对您没有帮助,但如果不是:Guava Library具有您所追求的确切功能
Iterators.filter(Iterator, Predicate)
Iterators.filter(Iterator, Predicate)
(You might have a look at how they did itfor inspiration)
(你可以看看他们是如何做到的以获得灵感)
回答by Jimmy Jia
how about my version? the next() method could be a little easy to understand compare to the previous examples.
我的版本呢?与前面的示例相比,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();
}
}
}