Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement this FilteringIterator?

Tags:

java

iterator

  1. IObjectTest is a interface with a single boolean test(Object o) method

  2. 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.

like image 307
Leon Avatar asked Mar 29 '11 15:03

Leon


People also ask

How do you implement iterators?

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.

Where is the implementation of iterator in Java?

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.

Is filter an iterator?

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.


1 Answers

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);
}
like image 71
Roel Spilker Avatar answered Oct 22 '22 10:10

Roel Spilker