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.
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.
To implement an Iterator, we need a cursor or pointer to keep track of which element we currently are on. Depending on the underlying data structure, we can progress from one element to another. This is done in the next() method which returns the current element and the cursor advances to next element.
Iterator class in Java belongs to java. util package. The methods declared by the iterator class are as follows, boolean hasNext() – It returns true if there exists a next element in the collection otherwise returns false.
A second advantage of using filter() over a loop is that it returns a filter object, which is an iterator that yields values on demand, promoting a lazy evaluation strategy. Returning an iterator makes filter() more memory efficient than an equivalent for loop.
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)
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With