KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jga > util > FindIterator


1 // ============================================================================
2
// $Id: FindIterator.java,v 1.17 2005/08/02 23:45:22 davidahall Exp $
3
// Copyright (c) 2002-2005 David A. Hall
4
// ============================================================================
5
// The contents of this file are subject to the Common Development and
6
// Distribution License (CDDL), Version 1.0 (the License); you may not use this
7
// file except in compliance with the License. You should have received a copy
8
// of the the License along with this file: if not, a copy of the License is
9
// available from Sun Microsystems, Inc.
10
//
11
// http://www.sun.com/cddl/cddl.html
12
//
13
// From time to time, the license steward (initially Sun Microsystems, Inc.) may
14
// publish revised and/or new versions of the License. You may not use,
15
// distribute, or otherwise make this file available under subsequent versions
16
// of the License.
17
//
18
// Alternatively, the contents of this file may be used under the terms of the
19
// GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which
20
// case the provisions of the LGPL are applicable instead of those above. If you
21
// wish to allow use of your version of this file only under the terms of the
22
// LGPL, and not to allow others to use your version of this file under the
23
// terms of the CDDL, indicate your decision by deleting the provisions above
24
// and replace them with the notice and other provisions required by the LGPL.
25
// If you do not delete the provisions above, a recipient may use your version
26
// of this file under the terms of either the CDDL or the LGPL.
27
//
28
// This library is distributed in the hope that it will be useful,
29
// but WITHOUT ANY WARRANTY; without even the implied warranty of
30
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
31
// ============================================================================
32

33 package net.sf.jga.util;
34
35 import java.util.Iterator JavaDoc;
36 import java.util.NoSuchElementException JavaDoc;
37 import net.sf.jga.fn.UnaryFunctor;
38
39 /**
40  * Iterator that provides the ability to skip to the first/next element that
41  * meets a particular criteria.
42  * <p>
43  * Copyright &copy; 2003-2005 David A. Hall
44  *
45  * @author <a HREF="mailto:davidahall@users.sourceforge.net">David A. Hall</a>
46  **/

47
48 public class FindIterator<T> implements Iterator JavaDoc<T>, Iterable JavaDoc<T> {
49
50     // The next element in the base iterator to be returned
51
private T _next;
52
53     // The base iterator
54
private Iterator JavaDoc<? extends T> _base;
55
56     // Flag indicating that there is an element ready to be returned.
57
private Boolean JavaDoc _baseHasNext;
58     
59     /**
60      * Builds a FindIterator for the given iterator.
61      */

62     public FindIterator(Iterator JavaDoc<? extends T> iter) {
63         _base = (iter != null) ? iter : new EmptyIterator<T>();
64     }
65
66     /**
67      * Returns true if at least one instance remaining in the iteration yields
68      * true when passed to the filter. This operation can advance the base
69      * iterator. It will not, however, advance the base iterator if it is
70      * called multiple times in succession without having retrieved the value.
71      */

72     public boolean findNext(UnaryFunctor<T,Boolean JavaDoc> filter) {
73         if (filter == null)
74             return hasNext();
75         
76         // test if we've already advanced via hasNext or foundNext
77
if (_baseHasNext != null)
78         {
79             // if there is at least one more element to test
80
if (_baseHasNext)
81             {
82                 // if the next value to return passes the filter, then
83
// we already have the next item to be found.
84
if (filter.fn(_next)) {
85                     return true;
86                 }
87                 
88                 // otherwise fall through -- the current 'next' object doesn't
89
// pass the selection criteria, so we need to discard it
90
}
91             else {
92                 return false;
93             }
94         }
95
96         // we don't know if there is another element that passes the filter,
97
// so we advance the base iterator and test every item until we fall
98
// off the end or find an item that passes
99
while (_base.hasNext()) {
100             T elem = _base.next();
101             if (filter.fn(elem)) {
102                 _next = elem;
103                 _baseHasNext = Boolean.TRUE;
104                 return true;
105             }
106         }
107         
108         _next = null;
109         _baseHasNext = Boolean.FALSE;
110         return false;
111     }
112
113     
114     // - - - - - - - - - - -
115
// Iterable<T> interface
116
// - - - - - - - - - - -
117

118     public Iterator JavaDoc<T> iterator() { return this; }
119     
120     // - - - - - - - - - - - - -
121
// ListIterator<T> interface
122
// - - - - - - - - - - - - -
123

124     /**
125      * Returns true if there is at least one instance remaining in the
126      * iteration. This operation can advance the base iterator. It will not,
127      * however, advance the base iterator if it is called multiple times in
128      * succession without having retrieved the value.
129      */

130     public boolean hasNext(){
131         // test if we've already advanced via hasNext or foundNext
132
if (_baseHasNext != null) {
133             return _baseHasNext;
134         }
135
136         // set our internal flag to the value of base.hasNext().
137
// since our internal flag is now non-null, further tests of hasNext()
138
// will return without consulting the base iterator.
139
boolean b = _base.hasNext();
140         _baseHasNext = Boolean.valueOf(b);
141
142         // stash the next value returned by the base iterator, if any.
143
// User might intermix tests of hasNext() and findNext(): we'll
144
// need to stash these the consistently with the way that findNext()
145
// does, in order that they may interoperate correctly
146
if (b) {
147             _next = _base.next();
148         }
149         
150         return b;
151     }
152
153     public T next() {
154         // If the user hasn't checked, then we will and throw NSE if there;s
155
// nothing left.
156
if (_baseHasNext == null) {
157             if (!hasNext()) {
158                 throw new NoSuchElementException JavaDoc();
159             }
160         }
161         
162         // If he did check and there's nothing left and he called this method
163
// anyway, throw NSE
164
else {
165             if (!_baseHasNext) {
166                 throw new NoSuchElementException JavaDoc();
167             }
168         }
169
170         // Return the next value, and reset everything
171
T val = _next;
172         _next = null;
173         _baseHasNext = null;
174         return val;
175     }
176
177     public void remove() { throw new UnsupportedOperationException JavaDoc(); }
178 }
179
Popular Tags