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.collections4.iterators;
18
19 import java.util.Iterator;
20
21 import org.apache.commons.collections4.Transformer;
22
23 /**
24 * Decorates an iterator such that each element returned is transformed.
25 *
26 * @param <I> the type of the input to the function.
27 * @param <O> the type of the result of the function.
28 * @since 1.0
29 */
30 public class TransformIterator<I, O> implements Iterator<O> {
31
32 /** The iterator being used */
33 private Iterator<? extends I> iterator;
34 /** The transformer being used */
35 private Transformer<? super I, ? extends O> transformer;
36
37 /**
38 * Constructs a new {@code TransformIterator} that will not function
39 * until the {@link #setIterator(Iterator) setIterator} and
40 * {@link #setTransformer(Transformer)} methods are invoked.
41 */
42 public TransformIterator() {
43 }
44
45 /**
46 * Constructs a new {@code TransformIterator} that won't transform
47 * elements from the given iterator.
48 *
49 * @param iterator the iterator to use
50 */
51 public TransformIterator(final Iterator<? extends I> iterator) {
52 this.iterator = iterator;
53 }
54
55 /**
56 * Constructs a new {@code TransformIterator} that will use the
57 * given iterator and transformer. If the given transformer is null,
58 * then objects will not be transformed.
59 *
60 * @param iterator the iterator to use
61 * @param transformer the transformer to use
62 */
63 public TransformIterator(final Iterator<? extends I> iterator,
64 final Transformer<? super I, ? extends O> transformer) {
65 this.iterator = iterator;
66 this.transformer = transformer;
67 }
68
69 /**
70 * Gets the iterator this iterator is using.
71 *
72 * @return the iterator.
73 */
74 public Iterator<? extends I> getIterator() {
75 return iterator;
76 }
77
78 /**
79 * Gets the transformer this iterator is using.
80 *
81 * @return the transformer.
82 */
83 public Transformer<? super I, ? extends O> getTransformer() {
84 return transformer;
85 }
86
87 @Override
88 public boolean hasNext() {
89 return iterator.hasNext();
90 }
91
92 /**
93 * Gets the next object from the iteration, transforming it using the
94 * current transformer. If the transformer is null, no transformation
95 * occurs and the object from the iterator is returned directly.
96 *
97 * @return the next object
98 * @throws java.util.NoSuchElementException if there are no more elements
99 */
100 @Override
101 public O next() {
102 return transform(iterator.next());
103 }
104
105 @Override
106 public void remove() {
107 iterator.remove();
108 }
109
110 /**
111 * Sets the iterator for this iterator to use.
112 * If iteration has started, this effectively resets the iterator.
113 *
114 * @param iterator the iterator to use
115 */
116 public void setIterator(final Iterator<? extends I> iterator) {
117 this.iterator = iterator;
118 }
119
120 /**
121 * Sets the transformer this the iterator to use.
122 * A null transformer is a no-op transformer.
123 *
124 * @param transformer the transformer to use
125 */
126 public void setTransformer(final Transformer<? super I, ? extends O> transformer) {
127 this.transformer = transformer;
128 }
129
130 /**
131 * Transforms the given object using the transformer.
132 * If the transformer is null, the original object is returned as-is.
133 *
134 * @param source the object to transform
135 * @return the transformed object
136 */
137 protected O transform(final I source) {
138 return transformer.apply(source);
139 }
140 }