View Javadoc

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      private T next = null;
38      private boolean nextSet = false;
39      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      public FilteredIterator(Iterator<? extends T> iterator, UnaryPredicate<? super T> predicate) {
49          if (null == iterator) {
50              throw new IllegalArgumentException("Iterator argument was null");
51          }
52          if (null == predicate) {
53              throw new IllegalArgumentException("filtering UnaryPredicate argument was null");
54          }
55          this.predicate = predicate;
56          this.iterator = iterator;
57      }
58  
59      // iterator methods
60      // ------------------------------------------------------------------------
61  
62      /**
63       * {@inheritDoc}
64       * @see java.util.Iterator#hasNext()
65       */
66      public boolean hasNext() {
67          return nextSet || setNext();
68      }
69  
70      /**
71       * {@inheritDoc}
72       * @see java.util.Iterator#next()
73       */
74      public T next() {
75          if (hasNext()) {
76              return returnNext();
77          }
78          throw new NoSuchElementException();
79      }
80  
81      /**
82       * {@inheritDoc}
83       * @see java.util.Iterator#remove()
84       */
85      public void remove() {
86          if (canRemove) {
87              canRemove = false;
88              iterator.remove();
89          } else {
90              throw new IllegalStateException();
91          }
92      }
93  
94      /**
95       * {@inheritDoc}
96       */
97      public boolean equals(Object obj) {
98          if (obj == this) {
99              return true;
100         }
101         if (!(obj instanceof FilteredIterator<?>)) {
102             return false;
103         }
104         FilteredIterator<?> that = (FilteredIterator<?>) obj;
105         return predicate.equals(that.predicate) && iterator.equals(that.iterator);
106     }
107 
108     /**
109      * {@inheritDoc}
110      */
111     public int hashCode() {
112         int hash = "FilteredIterator".hashCode();
113         hash <<= 2;
114         hash ^= predicate.hashCode();
115         hash <<= 2;
116         hash ^= iterator.hashCode();
117         return hash;
118     }
119 
120     /**
121      * {@inheritDoc}
122      */
123     public String toString() {
124         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         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         while (iterator.hasNext()) {
148             canRemove = false;
149             T obj = iterator.next();
150             if (predicate.test(obj)) {
151                 nextSet = true;
152                 next = obj;
153                 return true;
154             }
155         }
156         next = null;
157         nextSet = false;
158         return false;
159     }
160 
161     /**
162      * Get the next element.
163      * @return next element.
164      */
165     private T returnNext() {
166         T temp = next;
167         canRemove = true;
168         next = null;
169         nextSet = false;
170         return temp;
171     }
172 
173 }