/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
* or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package org.apache.commons.collections4.iterators;
import java.util.Iterator;
import org.apache.commons.collections4.ResettableIterator;
Adapter to make an Iterator
instance appear to be an Iterable
instance. The iterable can be constructed in one of two variants: single use, multiple use. In the single use iterable case, the iterable is only usable for one iterative operation over the source iterator. Subsequent iterative operations use the same, exhausted source iterator. To create a single use iterable, construct a new IteratorIterable
using a Iterator
that is NOT a ResettableIterator
iterator:
Iterator<Integer> iterator = // some non-resettable iterator
Iterable<Integer> iterable = new IteratorIterable<Integer>(iterator);
In the multiple use iterable case, the iterable is usable for any number of iterative operations over the source iterator. Of special note, even though the iterable supports multiple iterations, it does not support concurrent iterations. To implicitly create a multiple use iterable, construct a new IteratorIterable
using a ResettableIterator
iterator:
Integer[] array = {Integer.valueOf(1),Integer.valueOf(2),Integer.valueOf(3)};
Iterator<Integer> iterator = IteratorUtils.arrayIterator(array); // a resettable iterator
Iterable<Integer> iterable = new IteratorIterable<Integer>(iterator);
A multiple use iterable can also be explicitly constructed using any Iterator
and specifying true
for the
multipleUse
flag:
Iterator<Integer> iterator = // some non-resettable iterator
Iterable<Integer> iterable = new IteratorIterable<Integer>(iterator, true);
Since: 4.0
/**
* Adapter to make an {@link Iterator Iterator} instance appear to be an
* {@link Iterable Iterable} instance. The iterable can be constructed in one
* of two variants: single use, multiple use.
*
* <p>
* In the single use iterable case, the iterable is only usable for one
* iterative operation over the source iterator. Subsequent iterative
* operations use the same, exhausted source iterator. To create a single use
* iterable, construct a new {@link IteratorIterable} using a {@link Iterator}
* that is NOT a {@link ResettableIterator} iterator:
* </p>
*
* <pre>
* Iterator<Integer> iterator = // some non-resettable iterator
* Iterable<Integer> iterable = new IteratorIterable<Integer>(iterator);
* </pre>
*
* <p>
* In the multiple use iterable case, the iterable is usable for any number of
* iterative operations over the source iterator. Of special note, even though
* the iterable supports multiple iterations, it does not support concurrent
* iterations. To implicitly create a multiple use iterable, construct a new
* {@link IteratorIterable} using a {@link ResettableIterator} iterator:
* </p>
*
* <pre>
* Integer[] array = {Integer.valueOf(1),Integer.valueOf(2),Integer.valueOf(3)};
* Iterator<Integer> iterator = IteratorUtils.arrayIterator(array); // a resettable iterator
* Iterable<Integer> iterable = new IteratorIterable<Integer>(iterator);
* </pre>
*
* <p>
* A multiple use iterable can also be explicitly constructed using any
* {@link Iterator} and specifying <code>true</code> for the
* <code>multipleUse</code> flag:
* </p>
*
* <pre>
* Iterator<Integer> iterator = // some non-resettable iterator
* Iterable<Integer> iterable = new IteratorIterable<Integer>(iterator, true);
* </pre>
*
* @since 4.0
*/
public class IteratorIterable<E> implements Iterable<E> {
Factory method to create an Iterator
from another iterator over objects of a different subtype. /**
* Factory method to create an {@link Iterator Iterator} from another
* iterator over objects of a different subtype.
*/
private static <E> Iterator<E> createTypesafeIterator(final Iterator<? extends E> iterator) {
return new Iterator<E>() {
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public E next() {
return iterator.next();
}
@Override
public void remove() {
iterator.remove();
}
};
}
the iterator being adapted into an iterable. /** the iterator being adapted into an iterable. */
private final Iterator<? extends E> iterator;
the iterator parameterized as the iterator()
return type. /** the iterator parameterized as the {@link #iterator()} return type. */
private final Iterator<E> typeSafeIterator;
Constructs a new IteratorIterable
that will use the given
iterator.
Params: - iterator – the iterator to use.
/**
* Constructs a new <code>IteratorIterable</code> that will use the given
* iterator.
*
* @param iterator the iterator to use.
*/
public IteratorIterable(final Iterator<? extends E> iterator) {
this(iterator, false);
}
Constructs a new IteratorIterable
that will use the given
iterator.
Params: - iterator – the iterator to use.
- multipleUse –
true
if the new iterable can be used in multiple iterations
/**
* Constructs a new <code>IteratorIterable</code> that will use the given
* iterator.
*
* @param iterator the iterator to use.
* @param multipleUse <code>true</code> if the new iterable can be used in multiple iterations
*/
public IteratorIterable(final Iterator<? extends E> iterator, final boolean multipleUse) {
super();
if (multipleUse && !(iterator instanceof ResettableIterator)) {
this.iterator = new ListIteratorWrapper<>(iterator);
} else {
this.iterator = iterator;
}
this.typeSafeIterator = createTypesafeIterator(this.iterator);
}
Gets the iterator wrapped by this iterable.
Returns: the iterator
/**
* Gets the iterator wrapped by this iterable.
*
* @return the iterator
*/
@Override
public Iterator<E> iterator() {
if (iterator instanceof ResettableIterator) {
((ResettableIterator<? extends E>)iterator).reset();
}
return typeSafeIterator;
}
}