A ListIterator is equivalent to the List interface. To demonstrate this, I'm writing a IteratorList class which implements the List interface over an underlying ListIterator; it's actually quite simple. More fun with iterators! Here it is (note, not tested—I just wanted to sketch it out to see what it'd look like):
/*
* IteratorList.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 June 4, 2003.
*/
package hm.binkley.util;
import java.lang.reflect.Array;
import java.util.AbstractList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
* <code>IteratorList</code> implements <code>List</code> from an
* underlying <code>ListIterator</code>.
*
* @author <a href="mailto:binkley@alumni.rice.edu">B. K. Oxley (binkley)</a>
* @version 1.0
*/
public class IteratorList extends AbstractList {
/** The underlying list iterator. */
private final ListIterator it;
/**
* Constructs a <code>IteratorList</code> code from an underyling
* <code>ListIterator</code> object.
*
* @param it the list iterator
*/
public IteratorList(ListIterator it) {
this.it = it;
}
/**
* Resets the underlying list iterator back to its starting state.
*/
private void reset() {
while (it.hasPrevious())
it.previous();
}
/**
* Positions the underlying iterator before <var>index</var>. The
* caller needs to then call {@link #next()} as required.
*
* @param index the index
* @throws IndexOutOfBoundsException if <var>index</var> is out of
* range
*/
private void scrollTo(int index) {
if (index < 0)
throw new IndexOutOfBoundsException();
// Ensure we call one extra next for the index itself
while (index-- > 0)
if (it.hasNext())
it.next();
else
throw new IndexOutOfBoundsException();
}
/** {@inheritDoc} */
public int size() {
int n = 0;
for ( ; it.hasNext(); ++n)
it.next();
reset();
return n;
}
/** {@inheritDoc} */
public Object get(int index) {
try {
scrollTo(index);
if (it.hasNext())
return it.next();
else
throw new IndexOutOfBoundsException();
}
finally {
reset();
}
}
/** {@inheritDoc} */
public Object set(int index, Object element) {
try {
scrollTo(index);
if (it.hasNext()) {
Object old = it.next();
it.set(element);
return old;
}
else
throw new IndexOutOfBoundsException();
}
finally {
reset();
}
}
/** {@inheritDoc} */
public void add(int index, Object element) {
try {
scrollTo(index);
if (it.hasNext()) {
it.next();
it.add(element);
}
else
throw new IndexOutOfBoundsException();
}
finally {
reset();
}
}
/** {@inheritDoc} */
public Object remove(int index) {
try {
scrollTo(index);
if (it.hasNext()) {
Object old = it.next();
it.remove();
return old;
}
else
throw new IndexOutOfBoundsException();
}
finally {
reset();
}
}
}
No comments:
Post a Comment