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    
021    import org.apache.commons.functor.UnaryFunction;
022    
023    /**
024     * Iterator that transforms another Iterator by applying a UnaryFunction to each returned element.
025     * @version $Revision: 1156793 $ $Date: 2011-08-11 22:06:24 +0200 (Thu, 11 Aug 2011) $
026     * @author Rodney Waldhoff
027     */
028    public final class TransformedIterator<E, T> implements Iterator<T> {
029    
030        // attributes
031        // ------------------------------------------------------------------------
032    
033        private final UnaryFunction<? super E, ? extends T> function;
034        private final Iterator<? extends E> iterator;
035    
036        // constructor
037        // ------------------------------------------------------------------------
038        /**
039         * Create a new TransformedIterator.
040         * @param iterator Iterator to decorate
041         * @param function to apply
042         */
043        public TransformedIterator(Iterator<? extends E> iterator, UnaryFunction<? super E, ? extends T> function) {
044            if (null == iterator) {
045                throw new IllegalArgumentException("Iterator argument was null");
046            }
047            if (null == function) {
048                throw new IllegalArgumentException("filtering UnaryFunction argument was null");
049            }
050            this.function = function;
051            this.iterator = iterator;
052        }
053    
054        // iterator methods
055        // ------------------------------------------------------------------------
056    
057        /**
058         * {@inheritDoc}
059         * @see java.util.Iterator#hasNext()
060         */
061        public boolean hasNext() {
062            return iterator.hasNext();
063        }
064    
065        /**
066         * {@inheritDoc}
067         * @see java.util.Iterator#next()
068         */
069        public T next() {
070            return function.evaluate(iterator.next());
071        }
072    
073        /**
074         * {@inheritDoc}
075         * @see java.util.Iterator#remove()
076         */
077        public void remove() {
078            iterator.remove();
079        }
080    
081        /**
082         * {@inheritDoc}
083         */
084        public boolean equals(Object obj) {
085            if (obj == this) {
086                return true;
087            }
088            if (!(obj instanceof TransformedIterator<?, ?>)) {
089                return false;
090            }
091            TransformedIterator<?, ?> that = (TransformedIterator<?, ?>) obj;
092            return function.equals(that.function) && iterator.equals(that.iterator);
093        }
094    
095        /**
096         * {@inheritDoc}
097         */
098        public int hashCode() {
099            int hash = "TransformedIterator".hashCode();
100            hash <<= 2;
101            hash ^= function.hashCode();
102            hash <<= 2;
103            hash ^= iterator.hashCode();
104            return hash;
105        }
106    
107        /**
108         * {@inheritDoc}
109         */
110        public String toString() {
111            return "TransformedIterator<" + iterator + "," + function + ">";
112        }
113    
114        // class methods
115        // ------------------------------------------------------------------------
116        /**
117         * Get a Transformed Iterator instance.
118         * @param iter to decorate, if null result is null
119         * @param func transforming function, cannot be null
120         * @return Iterator<T>
121         */
122        public static <E, T> Iterator<T> transform(Iterator<? extends E> iter, UnaryFunction<? super E, ? extends T> func) {
123            if (null == iter) {
124                return null;
125            }
126            return new TransformedIterator<E, T>(iter, func);
127        }
128    
129        /**
130         * Get an Iterator instance that may be transformed.
131         * @param iter to decorate, if null result is null
132         * @param func transforming function, if null result is iter
133         * @return Iterator<?>
134         */
135        public static <E> Iterator<?> maybeTransform(Iterator<? extends E> iter, UnaryFunction<? super E, ?> func) {
136            return null == func ? (null == iter ? null : iter) : new TransformedIterator<E, Object>(iter, func);
137        }
138    
139    }