001: package uk.co.jezuk.mango.iterators;
002:
003: /**
004: * A <code>BoundedIterator</code> enumerates of a subset of a collection, in the
005: * range [<code>start</code>, <code>end</code>). A normal <code>java.util.Iterator</code>
006: * traverses [0, collection.size()), so BoundedIterator allows you
007: * to pick out a sub-set without using <code>list.subList()</code>
008: * or equivalent.
009: *
010: * @author Jez Higgins, jez@jezuk.co.uk
011: * @version $Id: BoundedIterator.java 49 2002-06-11 14:43:09Z jez $
012: */
013: public class BoundedIterator implements java.util.Iterator {
014: /**
015: * This form of <code>BoundedIterator</code> limits the range traversed by the
016: * underlying <code>iterator</code>. <p>
017: * If <code>iterator.hasNext()</code> fails before <code>end</code> is
018: * reached, the traversal will stop prematurely.<p>
019: * @throws java.lang.IndexOutOfBoundsException if start<0, end<0 or start>end
020: */
021: public BoundedIterator(java.util.Iterator iterator, int start,
022: int end) {
023: iter_ = new iteratorWrapper(iterator, start, end);
024: } // BoundIterator
025:
026: /**
027: * The form of <code>BoundedIterator</code> uses indexed access directly into
028: * the list.<p>
029: * If <code>end</code> > list.end() the travesal will stop with
030: * list.end() is reached.<p>
031: * For <code>ArrayLists</code> and <code>Vectors</code> it
032: * should be slightly quicker. For <code>LinkedLists</code> it
033: * will be slower.
034: * @throws java.lang.IndexOutOfBoundsException if start<0, end<0 or start>end
035: */
036: public BoundedIterator(java.util.List list, int start, int end) {
037: iter_ = new listIterator(list, start, end);
038: } // BoundedIterator
039:
040: public boolean hasNext() {
041: return iter_.hasNext();
042: } // hasNext
043:
044: public Object next() {
045: return iter_.next();
046: } // next
047:
048: public void remove() {
049: iter_.remove();
050: } // remove
051:
052: private java.util.Iterator iter_;
053:
054: ///////////////////////////////////////////////////
055: static private void checkConstraints(int start, int end) {
056: if (start < 0)
057: throw new IndexOutOfBoundsException("start < 0");
058: if (end < 0)
059: throw new IndexOutOfBoundsException("end < 0");
060: if (start > end)
061: throw new IndexOutOfBoundsException("start > end");
062: } // checkConstraints
063:
064: static private class iteratorWrapper implements java.util.Iterator {
065: iteratorWrapper(java.util.Iterator iterator, int start, int end) {
066: BoundedIterator.checkConstraints(start, end);
067:
068: iter_ = iterator;
069: for (index_ = 0; iter_.hasNext() && index_ < start; ++index_, iter_
070: .next())
071: ;
072:
073: end_ = iter_.hasNext() ? end : index_;
074: } // iteratorWrapper
075:
076: public boolean hasNext() {
077: end_ = iter_.hasNext() ? end_ : index_;
078: return (index_ < end_);
079: } // hasNext()
080:
081: public Object next() {
082: ++index_;
083: return iter_.next();
084: } // next
085:
086: public void remove() {
087: iter_.remove();
088: } // remove
089:
090: private java.util.Iterator iter_;
091: private int index_;
092: private int end_;
093: } // iteratorWrapper
094:
095: static private class listIterator implements java.util.Iterator {
096: listIterator(java.util.List list, int start, int end) {
097: BoundedIterator.checkConstraints(start, end);
098:
099: list_ = list;
100: index_ = start;
101: end_ = end;
102:
103: if (end_ > list_.size())
104: end_ = list.size();
105: } // listIterator
106:
107: public boolean hasNext() {
108: return (index_ < end_);
109: } // hasNext
110:
111: public Object next() {
112: return list_.get(index_++);
113: } // next
114:
115: public void remove() {
116: list_.remove(index_ - 1);
117: } // remove
118:
119: private java.util.List list_;
120: private int index_;
121: private int end_;
122: } // listIterator
123: } // BoundedIterator
|