1 | package spiffy.core.util; |
2 | |
3 | import java.util.Iterator; |
4 | |
5 | /** |
6 | * The PushBackIterator enables you to iterate and push back elements should you find that "you have come to far". You |
7 | * can push elements back in the iterator which then will be re-visited upon the subsequent call to <tt>next()</tt> |
8 | * |
9 | * @author Kasper B. Graversen |
10 | */ |
11 | public class PushBackIterator<T> implements Iterator<T> { |
12 | /** the iterator we wrap */ |
13 | private final Iterator<T> iterator; |
14 | |
15 | /** when pushing back, fill this cache */ |
16 | private T pushBackCache = null; |
17 | |
18 | /** record last fetched element such that we know what to push back */ |
19 | private T lastFetchedElement = null; |
20 | |
21 | /** |
22 | * @param iterator |
23 | * the iterator to wrap in order to get the push back functionality. |
24 | */ |
25 | public PushBackIterator(final Iterator<T> iterator) { |
26 | this.iterator = iterator; |
27 | } |
28 | |
29 | /** |
30 | * Returns true if the iteration has more elements. (In other words, returns true if next would return an element rather |
31 | * than throwing an exception.) |
32 | * |
33 | * @return true if the iterator has more elements. |
34 | */ |
35 | public boolean hasNext() { |
36 | return iterator.hasNext() || pushBackCache != null; |
37 | } |
38 | |
39 | /** |
40 | * Returns the next element in the iteration. Calling this method repeatedly until the hasNext() method returns false |
41 | * will return each element in the underlying collection exactly once. |
42 | * |
43 | * @return the next element in the iteration. |
44 | */ |
45 | public T next() { |
46 | // if we have something in the cache.. use that |
47 | if( pushBackCache != null ) { |
48 | lastFetchedElement = pushBackCache; |
49 | pushBackCache = null; |
50 | } else { |
51 | lastFetchedElement = iterator.next(); |
52 | } |
53 | return lastFetchedElement; |
54 | } |
55 | |
56 | /** |
57 | * Push back the last fetched element |
58 | */ |
59 | public void pushBack() { |
60 | if( lastFetchedElement == null ) |
61 | throw new IllegalStateException( |
62 | "next() must be called before pushBack(). Cannot push back non-existing element..."); |
63 | if( pushBackCache != null ) |
64 | throw new IllegalStateException("Cannot push back more than one object!"); |
65 | pushBackCache = lastFetchedElement; |
66 | } |
67 | |
68 | /** |
69 | * Operation currently not supported |
70 | */ |
71 | public void remove() { |
72 | throw new RuntimeException("Operation not supported yet..."); |
73 | } |
74 | } |