1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections4.iterators;
18
19 import java.util.ListIterator;
20 import java.util.NoSuchElementException;
21
22 import org.apache.commons.collections4.Predicate;
23
24
25
26
27
28
29
30
31
32
33 public class FilterListIterator<E> implements ListIterator<E> {
34
35
36 private ListIterator<? extends E> iterator;
37
38
39 private Predicate<? super E> predicate;
40
41
42
43
44
45 private E nextObject;
46
47
48
49
50
51 private boolean nextObjectSet;
52
53
54
55
56
57 private E previousObject;
58
59
60
61
62
63 private boolean previousObjectSet;
64
65
66
67
68 private int nextIndex;
69
70
71
72
73
74
75 public FilterListIterator() {
76 }
77
78
79
80
81
82
83
84 public FilterListIterator(final ListIterator<? extends E> iterator ) {
85 this.iterator = iterator;
86 }
87
88
89
90
91
92
93
94 public FilterListIterator(final ListIterator<? extends E> iterator, final Predicate<? super E> predicate) {
95 this.iterator = iterator;
96 this.predicate = predicate;
97 }
98
99
100
101
102
103
104
105 public FilterListIterator(final Predicate<? super E> predicate) {
106 this.predicate = predicate;
107 }
108
109
110
111
112
113 @Override
114 public void add(final E o) {
115 throw new UnsupportedOperationException("FilterListIterator.add(Object) is not supported.");
116 }
117
118 private void clearNextObject() {
119 nextObject = null;
120 nextObjectSet = false;
121 }
122
123 private void clearPreviousObject() {
124 previousObject = null;
125 previousObjectSet = false;
126 }
127
128
129
130
131
132
133 public ListIterator<? extends E> getListIterator() {
134 return iterator;
135 }
136
137
138
139
140
141
142 public Predicate<? super E> getPredicate() {
143 return predicate;
144 }
145
146 @Override
147 public boolean hasNext() {
148 return nextObjectSet || setNextObject();
149 }
150
151 @Override
152 public boolean hasPrevious() {
153 return previousObjectSet || setPreviousObject();
154 }
155
156 @Override
157 public E next() {
158 if (!nextObjectSet && !setNextObject()) {
159 throw new NoSuchElementException();
160 }
161 nextIndex++;
162 final E temp = nextObject;
163 clearNextObject();
164 return temp;
165 }
166
167 @Override
168 public int nextIndex() {
169 return nextIndex;
170 }
171
172 @Override
173 public E previous() {
174 if (!previousObjectSet && !setPreviousObject()) {
175 throw new NoSuchElementException();
176 }
177 nextIndex--;
178 final E temp = previousObject;
179 clearPreviousObject();
180 return temp;
181 }
182
183 @Override
184 public int previousIndex() {
185 return nextIndex-1;
186 }
187
188
189 @Override
190 public void remove() {
191 throw new UnsupportedOperationException("FilterListIterator.remove() is not supported.");
192 }
193
194
195
196
197
198
199 @Override
200 public void set(final E o) {
201 throw new UnsupportedOperationException("FilterListIterator.set(Object) is not supported.");
202 }
203
204
205
206
207
208
209
210 public void setListIterator(final ListIterator<? extends E> iterator) {
211 this.iterator = iterator;
212 }
213
214 private boolean setNextObject() {
215
216
217
218
219 if (previousObjectSet) {
220 clearPreviousObject();
221 if (!setNextObject()) {
222 return false;
223 }
224 clearNextObject();
225 }
226
227 if (iterator == null) {
228 return false;
229 }
230 while (iterator.hasNext()) {
231 final E object = iterator.next();
232 if (predicate.evaluate(object)) {
233 nextObject = object;
234 nextObjectSet = true;
235 return true;
236 }
237 }
238 return false;
239 }
240
241
242
243
244
245
246 public void setPredicate(final Predicate<? super E> predicate) {
247 this.predicate = predicate;
248 }
249
250 private boolean setPreviousObject() {
251
252
253
254
255 if (nextObjectSet) {
256 clearNextObject();
257 if (!setPreviousObject()) {
258 return false;
259 }
260 clearPreviousObject();
261 }
262
263 if (iterator == null) {
264 return false;
265 }
266 while (iterator.hasPrevious()) {
267 final E object = iterator.previous();
268 if (predicate.evaluate(object)) {
269 previousObject = object;
270 previousObjectSet = true;
271 return true;
272 }
273 }
274 return false;
275 }
276
277 }