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 * https://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 018package org.apache.commons.collections4.iterators; 019 020import java.util.Iterator; 021import java.util.Objects; 022 023import org.apache.commons.collections4.Transformer; 024 025/** 026 * Decorates an iterator such that each element returned is transformed. 027 * 028 * @param <I> The type of the input to the function. 029 * @param <O> The type of the result of the function. 030 * @since 1.0 031 */ 032public class TransformIterator<I, O> implements Iterator<O> { 033 034 /** The iterator being used */ 035 private Iterator<? extends I> iterator; 036 /** The transformer being used */ 037 private Transformer<? super I, ? extends O> transformer; 038 039 /** 040 * Constructs a new {@code TransformIterator} that will not function until the {@link #setIterator(Iterator) setIterator} and 041 * {@link #setTransformer(Transformer)} methods are invoked. 042 */ 043 public TransformIterator() { 044 } 045 046 /** 047 * Constructs a new {@code TransformIterator} that won't transform elements from the given iterator. 048 * 049 * @param iterator The iterator to use. 050 */ 051 public TransformIterator(final Iterator<? extends I> iterator) { 052 this(iterator, null); 053 } 054 055 /** 056 * Constructs a new {@code TransformIterator} that will use the given iterator and transformer. If the given transformer is null, then objects will not be 057 * transformed. 058 * 059 * @param iterator The iterator to use, may not be null. 060 * @param transformer The transformer to use, may be null to pass elements through unchanged 061 */ 062 public TransformIterator(final Iterator<? extends I> iterator, final Transformer<? super I, ? extends O> transformer) { 063 this.iterator = Objects.requireNonNull(iterator, "iterator"); 064 this.transformer = transformer; 065 } 066 067 /** 068 * Gets the iterator this iterator is using. 069 * 070 * @return The iterator. 071 */ 072 public Iterator<? extends I> getIterator() { 073 return iterator; 074 } 075 076 /** 077 * Gets the transformer this iterator is using. 078 * 079 * @return The transformer, may be null. 080 */ 081 public Transformer<? super I, ? extends O> getTransformer() { 082 return transformer; 083 } 084 085 @Override 086 public boolean hasNext() { 087 return iterator.hasNext(); 088 } 089 090 /** 091 * Gets the next object from the iteration, transforming it using the current transformer. If the transformer is null, no transformation occurs and the 092 * object from the iterator is returned directly. 093 * 094 * @return The next object. 095 * @throws java.util.NoSuchElementException if there are no more elements. 096 */ 097 @Override 098 public O next() { 099 return transform(iterator.next()); 100 } 101 102 @Override 103 public void remove() { 104 iterator.remove(); 105 } 106 107 /** 108 * Sets the iterator for this iterator to use. If iteration has started, this effectively resets the iterator. 109 * 110 * @param iterator The iterator to use. 111 */ 112 public void setIterator(final Iterator<? extends I> iterator) { 113 this.iterator = iterator; 114 } 115 116 /** 117 * Sets the transformer this the iterator to use. A null transformer is a no-op transformer. 118 * 119 * @param transformer The transformer to use, may be null to pass elements through unchanged. 120 */ 121 public void setTransformer(final Transformer<? super I, ? extends O> transformer) { 122 this.transformer = transformer; 123 } 124 125 /** 126 * Transforms the given object using the transformer. If the transformer is null, the original object is returned as-is. 127 * 128 * @param source The object to transform, may be null. 129 * @return The transformed object, the original object the transformer is null. 130 */ 131 @SuppressWarnings("unchecked") 132 protected O transform(final I source) { 133 return transformer == null ? (O) source : transformer.apply(source); 134 } 135}