001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with this 004 * work for additional information regarding copyright ownership. The ASF 005 * licenses this file to You under the Apache License, Version 2.0 (the 006 * "License"); you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law 009 * or agreed to in writing, software distributed under the License is 010 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 011 * KIND, either express or implied. See the License for the specific language 012 * governing permissions and limitations under the License. 013 */ 014package org.apache.commons.collections4.iterators; 015 016import java.util.Iterator; 017 018import org.apache.commons.collections4.ResettableIterator; 019 020/** 021 * Adapter to make an {@link Iterator Iterator} instance appear to be an 022 * {@link Iterable Iterable} instance. The iterable can be constructed in one 023 * of two variants: single use, multiple use. 024 * 025 * <p> 026 * In the single use iterable case, the iterable is only usable for one 027 * iterative operation over the source iterator. Subsequent iterative 028 * operations use the same, exhausted source iterator. To create a single use 029 * iterable, construct a new {@link IteratorIterable} using a {@link Iterator} 030 * that is NOT a {@link ResettableIterator} iterator: 031 * <pre> 032 * Iterator<Integer> iterator = // some non-resettable iterator 033 * Iterable<Integer> iterable = new IteratorIterable<Integer>(iterator); 034 * </pre> 035 * </p> 036 * 037 * <p> 038 * In the multiple use iterable case, the iterable is usable for any number of 039 * iterative operations over the source iterator. Of special note, even though 040 * the iterable supports multiple iterations, it does not support concurrent 041 * iterations. To implicitly create a multiple use iterable, construct a new 042 * {@link IteratorIterable} using a {@link ResettableIterator} iterator: 043 * <pre> 044 * Integer[] array = {Integer.valueOf(1),Integer.valueOf(2),Integer.valueOf(3)}; 045 * Iterator<Integer> iterator = IteratorUtils.arrayIterator(array); // a resettable iterator 046 * Iterable<Integer> iterable = new IteratorIterable<Integer>(iterator); 047 * </pre> 048 * </p> 049 * 050 * <p> 051 * A multiple use iterable can also be explicitly constructed using any 052 * {@link Iterator} and specifying <code>true</code> for the 053 * <code>multipleUse</code> flag: 054 * <pre> 055 * Iterator<Integer> iterator = // some non-resettable iterator 056 * Iterable<Integer> iterable = new IteratorIterable<Integer>(iterator, true); 057 * </pre> 058 * </p> 059 * 060 * @since 4.0 061 * @version $Id: IteratorIterable.html 972421 2015-11-14 20:00:04Z tn $ 062 */ 063public class IteratorIterable<E> implements Iterable<E> { 064 065 /** 066 * Factory method to create an {@link Iterator Iterator} from another 067 * iterator over objects of a different subtype. 068 */ 069 private static <E> Iterator<E> createTypesafeIterator( 070 final Iterator<? extends E> iterator) { 071 return new Iterator<E>() { 072 public boolean hasNext() { 073 return iterator.hasNext(); 074 } 075 076 public E next() { 077 return iterator.next(); 078 } 079 080 public void remove() { 081 iterator.remove(); 082 } 083 }; 084 } 085 086 /** the iterator being adapted into an iterable. */ 087 private final Iterator<? extends E> iterator; 088 089 /** the iterator parameterized as the {@link #iterator()} return type. */ 090 private final Iterator<E> typeSafeIterator; 091 092 /** 093 * Constructs a new <code>IteratorIterable</code> that will use the given 094 * iterator. 095 * 096 * @param iterator the iterator to use. 097 */ 098 public IteratorIterable(final Iterator<? extends E> iterator) { 099 this(iterator, false); 100 } 101 102 /** 103 * Constructs a new <code>IteratorIterable</code> that will use the given 104 * iterator. 105 * 106 * @param iterator the iterator to use. 107 * @param multipleUse <code>true</code> if the new iterable can be used in multiple iterations 108 */ 109 public IteratorIterable(final Iterator<? extends E> iterator, final boolean multipleUse) { 110 super(); 111 if (multipleUse && !(iterator instanceof ResettableIterator)) { 112 this.iterator = new ListIteratorWrapper<E>(iterator); 113 } else { 114 this.iterator = iterator; 115 } 116 this.typeSafeIterator = createTypesafeIterator(this.iterator); 117 } 118 119 /** 120 * Gets the iterator wrapped by this iterable. 121 * 122 * @return the iterator 123 */ 124 public Iterator<E> iterator() { 125 if (iterator instanceof ResettableIterator) { 126 ((ResettableIterator<? extends E>)iterator).reset(); 127 } 128 return typeSafeIterator; 129 } 130}