Several separate Java projects have led to using the same simple Iterator
implementation, AbstractFilterIterator
. The idea is very simple: use a single method to filter an underlying Iterator
and decide which subset of the data to reveal. Perhaps it is more easily shown than explained, at least for me:
/* * AbstractFilterIterator.java * Copyright 2003 (C) B. K. Oxley (binkley) * <binkley@alumni.rice.edu> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * * Created on July 15, 2003. * * $Id: AbstractFilterIterator.java,v 1.1 2003/08/28 19:07:52 binkley Exp $ */ package hm.binkley.util; import java.util.Iterator; import java.util.ListIterator; /** * <code>AbstractFilterIterator</code> is a partial list iterator. * * @author <a href="mailto:binkley@alumni.rice.edu">B. K. Oxley (binkley)</a> * @version 1.0 */ public abstract class AbstractFilterIterator implements Iterator { /** <code>ListIterator</code> through the elements. */ protected ListIterator it; /** The current element after {@link #next()}. */ protected Object cursor = null; /** * Construct an <code>AbstractFilterIterator</code> from an * underlying iterator over a range. * * @param it the underlying iterator * */ protected AbstractFilterIterator(ListIterator it) { this.it = it; } /** * Match <var>element</var>. If the match is * <code>true</code>, <code>AbstractFilterIterator</code> will * present <var>element</var> in the view of the underlying * iterator. * * @param element the element to match * @return <code>true</code> if the element matches */ protected abstract boolean match(Object element); /** * Scroll the underlying iterator forward to find the next match. * Afterwards, use {@link #rewindNext(int)} to return the * underlying iterator to its original position. * * @return boolean <code>true</code> if there is a next match */ protected boolean findNext() { while (it.hasNext()) if (match(it.next())) return true; return false; } /** * Return the underlying iterator to previous position after an * earlier call to {@link #findNext()}. * * @param current the previous position */ protected void rewindNext(int current) { for (int next = it.nextIndex(); next > current; --next) it.previous(); } /** {@inheritDoc} */ public boolean hasNext() { // We have do it this way so that you can use next() // independently of hasNext(). int current = it.nextIndex(); boolean hasNext = findNext(); rewindNext(current); return hasNext; } /** {@inheritDoc} */ public Object next() { while (!match(cursor = it.next())) ; // nothing return cursor; } /** {@inheritDoc} */ public void remove() { it.remove(); } }
As you might suspect, AbstractFilterListIterator
is similar and extends AbstractFilterIterator
to include methods from ListIterator
. This is very straight-forward as AbstractFilterIterator
already has a protected ListIterator
member, it, to work with.
No comments:
Post a Comment