📄 iterators.java
字号:
/** * An <code>Iterators.Filter</code> filters the stream of objects * returned by another iterator by subjecting them to an acceptance * test. Instances are constructed with a specified iterator to be * filtered; this filter is saved in this class and should not be * accessed by other methods. Concrete subclasses must implement * {@link #accept(Object)}, which determines which of the elements * produced by the containediterator are returned. * * @author Bob Carpenter * @version 3.0 * @since LingPipe1.0 */ public static abstract class Filter<E> implements Iterator<E> { private final Iterator<? extends E> mIterator; private boolean mFoundNext = false; private E mNext; /** * Construct a filtered iterator from the specified iterator. * * @param iterator Contained iterator to be filtered. */ public Filter(Iterator<? extends E> iterator) { mIterator = iterator; } /** * Returns <code>true</code> for objects returned by the contained * iterator that should be returned by this iterator. * * @param x Object to test. * @return <code>true</code> if this object should be returned by * this iterator. */ abstract public boolean accept(E x); /** * Returns <code>true</code> if calls to <code>next()</code> will * return a value. * * <P><i>Implementation note:</i> This iterator stores the next * element in a local variable after calls to this method. Calls to * {@link #next()} remove this reference. * * @return <code>true</code> if calls to <code>next()</code> will * return a value. */ public boolean hasNext() { if (mFoundNext) return true; while (mIterator.hasNext()) { E y = mIterator.next(); if (accept(y)) { mFoundNext = true; mNext = y; return true; } } return false; } /** * Returns the next value from the contained iterator that is accepted. * Acceptance is determined by the method {@link #accept(Object)}. * * @return Next object from the underlying iterator that passes * the acceptance test. * @throws NoSuchElementException If there are no more elements in * the underlying iterator that pass the acceptance test. */ public E next() { if (!hasNext()) throw new NoSuchElementException(); mFoundNext = false; E result = mNext; mNext = null; return result; } /** * This operation is not supported. * * <P><i>Implementation Note:</i> Because calls to {@link * #hasNext()} must iterate over the contained iterator to find * the next acceptable object to return, it is not guaranteed that * the last element returned by this iterator is the same as the * last element returned by the underlying iterator. Thus the * underlying iterator can't be used to do the removal without * tripping the fail-fast behavior of {@link Iterator}. * * @throws UnsupportedOperationException Always. */ public void remove() { String msg = "Cannot remove from a filtered iterator."; throw new UnsupportedOperationException(msg); } } /** * An <code>Iterator.Modifier</code> uses a single abstract method * to operate on the elements returned by an underlying iterator * to return modified objects. The {@link #remove()} and {@link * #hasNext()} methods are simply passed to the underlying iterator. * This implements the filter pattern, which is known as a map in * functional programming. * * @author Bob Carpenter * @version 3.0 * @since LingPipe2.1 */ public static abstract class Modifier<E> implements Iterator<E> { private final Iterator<? extends E> mIt; /** * Construct a modifier from an underlying iterator. * * @param it Underlying iterator. */ public Modifier(Iterator<? extends E> it) { mIt = it; } /** * Remove the next element by delegating the call to the the * underlying iterator. */ public void remove() { mIt.remove(); } /** * Returns <code>true</code> if the underlying iterator has * more elements. This method is simply delegated to the * underlying iterator. * * @return <code>true</code> if this iterator has more * elements. */ public boolean hasNext() { return mIt.hasNext(); } /** * Returns the next element for this iterator, which is * the object returned by the underlying iterator after * undergoing modification by {@link #modify(Object)}. * * @return The modified next element from the underlying * iterator. */ public E next() { return modify(mIt.next()); } /** * This abstract method is applied to objects returned by the * underlying iterator to create the object returned by this * iterator. This method is called once for each call to * {@link #next()}. * * @param next Object returned by underlying iterator. * @return Object returned by this iterator. */ public abstract E modify(E next); } /** * An <code>Iterators.Buffered</code> uses a single method to return * objects, buffering the result and returning it as the next element * if it is non-<code>null</code>. This class does not support * <code>null</code> return values for {@link #next()}. The {@link * #remove()} operation is unsupported, but may be overridden. * * @author Bob Carpenter * @version 3.0 * @since LingPipe1.0 */ public static abstract class Buffered<E> implements Iterator<E> { private E mNext; /** * Construct a buffered iterator. This constructor does not * do anything. */ protected Buffered() { // do nothing } /** * Returns the next object for this iterator, or <code>null</code> * if there are no more objects. * * @return Next object for this iterator. */ protected abstract E bufferNext(); /** * Returns <code>true</code> if the next call to {@link #next()} * will return a non-<code>null</code> value. * * @return <code>true</code> if the next call to {@link #next()} * will return a non-<code>null</code> value. */ public boolean hasNext() { return mNext != null || (mNext = bufferNext()) != null; } /** * Returns the next object for this iterator. * * @return The next object for this iterator. * @throws NoSuchElementException If there are no more elements. */ public E next() { if (!hasNext()) throw new NoSuchElementException(); E result = mNext; mNext = null; return result; } /** * Throws an unsupported operation exception unless overridden by * a subclass. * * @throws UnsupportedOperationException Always. */ public void remove() { throw new UnsupportedOperationException(); } } /** * An <code>Iterators.Sequence</code> iterates over the elements of an * ordered sequence of iterators in turn. Each iterator is exhausted * before moving to the next. These iterators may be supplied as a * pair of iterators, as an array of iterators, or as an iterator of * iterators. The sequence iterator delegates calls to {@link * #next()} and {@link #remove()} to the relevant iterator in the * underlying sequence of iterators. For <code>next()</code>, this is * the current underlying iterator. For <code>remove()</code>, it's * the last iterator whose <code>next()</code> element was called, and * it throws an illegal state exception if there isn't one. * * <P><I>Implementation Note:</I> Because of the requirements of * {@link Iterator#remove()}, a reference to the last iterator is * kept, as well as to the current iterator. Otherwise, the sequence * iterator will release resources as soon as possible. If the * supplied sequence is an array, the elements will not be * automatically returned from that array; it is simply wrapped in an * instance of {@link Iterators.Array}. * * @author Bob Carpenter * @version 3.0 * @since LingPipe1.0 */ public static class Sequence<E> implements Iterator<E> { private final Iterator<? extends Iterator<? extends E>> mIterators; private Iterator<? extends E> mCurrentIterator; private Iterator<? extends E> mLastIteratorNextCalled; /** * Construct a sequenc iterator that calls the pair of * iterators specified in turn. * * @param iterator1 First iterator. * @param iterator2 Second iterator. */ public Sequence(Iterator<? extends E> iterator1, Iterator<? extends E> iterator2) { this(toIteratorIterator(iterator1,iterator2)); } /** * Construct a sequence iterator that calls the iterators in the * specified array in the order they are given in the array. * * @param iterators Sequence of iterators. */ public Sequence(Iterator<? extends E>[] iterators) { this(new Iterators.Array<Iterator<? extends E>>(iterators)); } /** * Construct a sequence iterator that calls the iterators returned * by the iterator of iterators specified. If one of the elements * is not an iterator, <code>hasNext()</code> and * <code>next()</code> will throw a * <code>ClassCastException</code>. * * @param iteratorOfIterators Iterator of iterators. */ public Sequence(Iterator<? extends Iterator<? extends E>> iteratorOfIterators) { mIterators = iteratorOfIterators; } /** * Returns <code>true</code> if this iterator has another element. * This sequence of iterators has another element if it has * another iterator that has another element. * * @return <code>true</code> if this sequence of iterators * has another iterator with another element. * @throws ClassCastException If an object is returned by * the iterator of iterators specified at construction time * that is not an iterator. */ public boolean hasNext() { if (mCurrentIterator == null) nextIterator(); // get started for (; mCurrentIterator != null; nextIterator()) if (mCurrentIterator.hasNext()) return true; return false; } /** * Return the next element returned by the next iterator in the * iterator sequence. * * @return The next object in the iteration. * @throws ClassCastException If an object is returned by * the iterator of iterators specified at construction time * that is not an iterator. */ public E next() { if (!hasNext()) throw new NoSuchElementException(); mLastIteratorNextCalled = mCurrentIterator; return mCurrentIterator.next(); } /** * Removes the last element returned by this iterator from the * collection underlying the iterator from which it was returned. * The method can only be called once per call to * <code>next()</code>. * @throws IllegalStateException If <code>next()</code> has not * yet been called, or <code>remove()</code> method has * been called after the last call to <code>next()</code>. */ public void remove() { if (mLastIteratorNextCalled == null) throw new IllegalStateException("next() not yet called."); mLastIteratorNextCalled.remove(); mLastIteratorNextCalled = null; } private void nextIterator() { // possible cast exception mCurrentIterator = mIterators.hasNext() ? mIterators.next() : null; } static <E> Iterator<? extends Iterator<? extends E>> toIteratorIterator(Iterator<? extends E> it1, Iterator<? extends E> it2) { ArrayList<Iterator<? extends E>> list = new ArrayList<Iterator<? extends E>>(2); list.add(it1); list.add(it2); return list.iterator(); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -