001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.functor.core.collection; 018 019 import java.util.Iterator; 020 import java.util.NoSuchElementException; 021 022 import org.apache.commons.functor.UnaryPredicate; 023 024 /** 025 * Iterator that filters another Iterator by only passing through those elements 026 * that are matched by a specified UnaryPredicate. 027 * @version $Revision: 1156789 $ $Date: 2011-08-11 22:05:09 +0200 (Thu, 11 Aug 2011) $ 028 * @author Rodney Waldhoff 029 */ 030 public final class FilteredIterator<T> implements Iterator<T> { 031 // attributes 032 // ------------------------------------------------------------------------ 033 034 private final UnaryPredicate<? super T> predicate; 035 private final Iterator<? extends T> iterator; 036 037 private T next = null; 038 private boolean nextSet = false; 039 private boolean canRemove = false; 040 041 // constructor 042 // ------------------------------------------------------------------------ 043 /** 044 * Create a new FilteredIterator. 045 * @param iterator to filter 046 * @param predicate to apply 047 */ 048 public FilteredIterator(Iterator<? extends T> iterator, UnaryPredicate<? super T> predicate) { 049 if (null == iterator) { 050 throw new IllegalArgumentException("Iterator argument was null"); 051 } 052 if (null == predicate) { 053 throw new IllegalArgumentException("filtering UnaryPredicate argument was null"); 054 } 055 this.predicate = predicate; 056 this.iterator = iterator; 057 } 058 059 // iterator methods 060 // ------------------------------------------------------------------------ 061 062 /** 063 * {@inheritDoc} 064 * @see java.util.Iterator#hasNext() 065 */ 066 public boolean hasNext() { 067 return nextSet || setNext(); 068 } 069 070 /** 071 * {@inheritDoc} 072 * @see java.util.Iterator#next() 073 */ 074 public T next() { 075 if (hasNext()) { 076 return returnNext(); 077 } 078 throw new NoSuchElementException(); 079 } 080 081 /** 082 * {@inheritDoc} 083 * @see java.util.Iterator#remove() 084 */ 085 public void remove() { 086 if (canRemove) { 087 canRemove = false; 088 iterator.remove(); 089 } else { 090 throw new IllegalStateException(); 091 } 092 } 093 094 /** 095 * {@inheritDoc} 096 */ 097 public boolean equals(Object obj) { 098 if (obj == this) { 099 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 }