Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
FilteredIterator |
|
| 3.0;3 |
1 | /* | |
2 | * Licensed to the Apache Software Foundation (ASF) under one or more | |
3 | * contributor license agreements. See the NOTICE file distributed with | |
4 | * this work for additional information regarding copyright ownership. | |
5 | * The ASF licenses this file to You under the Apache License, Version 2.0 | |
6 | * (the "License"); you may not use this file except in compliance with | |
7 | * the License. You may obtain a copy of the License at | |
8 | * | |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | * | |
11 | * Unless required by applicable law or agreed to in writing, software | |
12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | * See the License for the specific language governing permissions and | |
15 | * limitations under the License. | |
16 | */ | |
17 | package org.apache.commons.functor.core.collection; | |
18 | ||
19 | import java.util.Iterator; | |
20 | import java.util.NoSuchElementException; | |
21 | ||
22 | import org.apache.commons.functor.UnaryPredicate; | |
23 | ||
24 | /** | |
25 | * Iterator that filters another Iterator by only passing through those elements | |
26 | * that are matched by a specified UnaryPredicate. | |
27 | * @version $Revision: 1156789 $ $Date: 2011-08-11 22:05:09 +0200 (Thu, 11 Aug 2011) $ | |
28 | * @author Rodney Waldhoff | |
29 | */ | |
30 | public final class FilteredIterator<T> implements Iterator<T> { | |
31 | // attributes | |
32 | // ------------------------------------------------------------------------ | |
33 | ||
34 | private final UnaryPredicate<? super T> predicate; | |
35 | private final Iterator<? extends T> iterator; | |
36 | ||
37 | 68 | private T next = null; |
38 | 68 | private boolean nextSet = false; |
39 | 68 | private boolean canRemove = false; |
40 | ||
41 | // constructor | |
42 | // ------------------------------------------------------------------------ | |
43 | /** | |
44 | * Create a new FilteredIterator. | |
45 | * @param iterator to filter | |
46 | * @param predicate to apply | |
47 | */ | |
48 | 68 | public FilteredIterator(Iterator<? extends T> iterator, UnaryPredicate<? super T> predicate) { |
49 | 68 | if (null == iterator) { |
50 | 4 | throw new IllegalArgumentException("Iterator argument was null"); |
51 | } | |
52 | 64 | if (null == predicate) { |
53 | 2 | throw new IllegalArgumentException("filtering UnaryPredicate argument was null"); |
54 | } | |
55 | 62 | this.predicate = predicate; |
56 | 62 | this.iterator = iterator; |
57 | 62 | } |
58 | ||
59 | // iterator methods | |
60 | // ------------------------------------------------------------------------ | |
61 | ||
62 | /** | |
63 | * {@inheritDoc} | |
64 | * @see java.util.Iterator#hasNext() | |
65 | */ | |
66 | public boolean hasNext() { | |
67 | 332 | return nextSet || setNext(); |
68 | } | |
69 | ||
70 | /** | |
71 | * {@inheritDoc} | |
72 | * @see java.util.Iterator#next() | |
73 | */ | |
74 | public T next() { | |
75 | 188 | if (hasNext()) { |
76 | 182 | return returnNext(); |
77 | } | |
78 | 6 | throw new NoSuchElementException(); |
79 | } | |
80 | ||
81 | /** | |
82 | * {@inheritDoc} | |
83 | * @see java.util.Iterator#remove() | |
84 | */ | |
85 | public void remove() { | |
86 | 72 | if (canRemove) { |
87 | 64 | canRemove = false; |
88 | 64 | iterator.remove(); |
89 | } else { | |
90 | 8 | throw new IllegalStateException(); |
91 | } | |
92 | 64 | } |
93 | ||
94 | /** | |
95 | * {@inheritDoc} | |
96 | */ | |
97 | public boolean equals(Object obj) { | |
98 | 8 | if (obj == this) { |
99 | 2 | return true; |
100 | } | |
101 | 6 | if (!(obj instanceof FilteredIterator<?>)) { |
102 | 2 | return false; |
103 | } | |
104 | 4 | FilteredIterator<?> that = (FilteredIterator<?>) obj; |
105 | 4 | return predicate.equals(that.predicate) && iterator.equals(that.iterator); |
106 | } | |
107 | ||
108 | /** | |
109 | * {@inheritDoc} | |
110 | */ | |
111 | public int hashCode() { | |
112 | 6 | int hash = "FilteredIterator".hashCode(); |
113 | 6 | hash <<= 2; |
114 | 6 | hash ^= predicate.hashCode(); |
115 | 6 | hash <<= 2; |
116 | 6 | hash ^= iterator.hashCode(); |
117 | 6 | return hash; |
118 | } | |
119 | ||
120 | /** | |
121 | * {@inheritDoc} | |
122 | */ | |
123 | public String toString() { | |
124 | 6 | return "FilteredIterator<" + iterator + "," + predicate + ">"; |
125 | } | |
126 | ||
127 | // static methods | |
128 | // ------------------------------------------------------------------------ | |
129 | /** | |
130 | * Get a filtered Iterator instance applying <code>pred</code> to <code>iter</code>. | |
131 | * @param iter to filter | |
132 | * @param pred to apply | |
133 | * @return Iterator | |
134 | */ | |
135 | @SuppressWarnings("unchecked") | |
136 | public static <T> Iterator<T> filter(Iterator<? extends T> iter, UnaryPredicate<? super T> pred) { | |
137 | 70 | return null == pred ? (Iterator<T>) iter : (null == iter ? null : new FilteredIterator<T>(iter, pred)); |
138 | } | |
139 | ||
140 | // private | |
141 | // ------------------------------------------------------------------------ | |
142 | /** | |
143 | * Set next element. | |
144 | * @return whether the current iterator position is valid | |
145 | */ | |
146 | private boolean setNext() { | |
147 | 358 | while (iterator.hasNext()) { |
148 | 314 | canRemove = false; |
149 | 314 | T obj = iterator.next(); |
150 | 314 | if (predicate.test(obj)) { |
151 | 182 | nextSet = true; |
152 | 182 | next = obj; |
153 | 182 | return true; |
154 | } | |
155 | 132 | } |
156 | 44 | next = null; |
157 | 44 | nextSet = false; |
158 | 44 | return false; |
159 | } | |
160 | ||
161 | /** | |
162 | * Get the next element. | |
163 | * @return next element. | |
164 | */ | |
165 | private T returnNext() { | |
166 | 182 | T temp = next; |
167 | 182 | canRemove = true; |
168 | 182 | next = null; |
169 | 182 | nextSet = false; |
170 | 182 | return temp; |
171 | } | |
172 | ||
173 | } |