Some common iterators for Java
Overview
This is a collection of companion iterators for some commonly useful Iterable
implementations for the following use cases:
- Filtering and Converting
- Combining multiple
Iterators
- Inserting affix values
- Looking ahead
- Handling of
null
values - Handling of
remove()
operation - Iterating over single values
- Iterating over multiple values
- Iterating over primitive arrays
- Iterating over non-primitive arrays
- Iterating over other objects
- Iterating infinitely
- Keeping track of iteration index
- Counting up and down
This library is hosted in the Maven Central Repository. You can use it with the following coordinates:
<dependency>
<groupId>net.markenwerk</groupId>
<artifactId>commons-iterators</artifactId>
<version>3.2.1</version>
</dependency>
Consult the usage description and Javadoc for further information.
Usage
Filtering and Converting
This library provides the generic FilteredIterator
that takes an existing Iterator
and a Predicate
and filters out all values yielded by the given Iterator
that don't satisfy the given Predicate
.
Iterator<Foo> iterator = ...
// yields every foo from from iterator that matches the condition
Iterator<Foo> FilteredIterator = new FilteredIterator<>(iterator, new Predicate<Foo>(){
@Override
public boolean test(Object object) throws PredicateException {
return ...; // some condition
}
});
This library provides the generic ConvertingIterator
that takes an existing Iterator
and a Converter
and converts all values yielded by the given Iterator
and yields the converted values.
Iterator<Foo> iterator = ...
// yields a bar for every foo from from iterator
Iterator<Bar> convertingIterator = new ConvertingIterator<>(iterator, new Converter<Foo, Bar>(){
@Override
public Bar convert(Foo foo) throws ConverterException {
return ...; // some conversion
}
});
Combining multiple Iterators
This library provides the generic CombinedIterator
that takes multiple existing Iterators
and combines them into a single Iterator
that yields all values of all given Iterators
.
It can be constructed from an array or an arbitrary amount of known Iterators
.
Iterator<Foo> iterator1 = ...
Iterator<Foo> iterator2 = ...
// yields every foo from every iterator1 and iterator2
Iterator<Foo> combinedIterator = new CombinedIterator<>(iterator1, iterator2);
It can be constructed from an Iterable
of Iterators
(i.e. a List
).
List<Iterator<Foo>>[] iterators = ...
// yields every foo from every iterator from iterators
Iterator<Foo> combinedIterator = new CombinedIterator<>(iterators);
Inserting affix values
This library provides the generic PrefixedIterator
that takes an existing Iterator
and yields given prefix values before every value yielded by the given Iterator
.
Foo prefix = ...
Iterator<Foo> iterator = ...
// yields prefix and than every foo from iterator
Iterator<Foo> prefixedIterator = new PrefixedIterator<>(iterator, prefix);
This library provides the generic InfixedIterator
that takes an existing Iterator
and yields given infix values between every value yielded by the given Iterator
.
Foo infix = ...
Iterator<Foo> iterator = ...
// yields every foo from iterator, interspersed with the infix
Iterator<Foo> infixedIterator = new InfixedIterator<>(iterator, infix);
This library provides the generic SuffixedIterator
that takes an existing Iterator
and yields given suffix values after every value yielded by the given Iterator
.
Foo suffix = ...
Iterator<Foo> iterator = ...
// yields every foo from iterator and than prefix
Iterator<Foo> suffixedIterator = new SuffixedIterator<>(iterator, suffix);
Looking ahead
This library provides the generic LookAheadIterator
that takes an existing Iterator
and yield every value yielded by the given Iterator
wrapped in a LookAhead
that also contains the next value. This allows to peak into the future, while iterating through the given Iterator
.
Iterator<Foo> iterator = ...
// yields a look ahead for every foo from iterator
Iterator<LookAhead<Foo>> lookAheadIterator = new LookAheadIterator<>(iterator);
A LookAheadIterator
can be used to easily perform actions between every element yielded by the original Iterator
.
while (lookAheadIterator.hasNext()) {
LookAhead<Foo> lookAhead = lookAheadIterator.next();
// returns the current foo
Foo currentFoo = lookAhead.get()
doForEveryFoo(currentFoo);
// returns whether the look ahead has a next value
if (lookAhead.hasNext()) {
// returns the next foo without modifying lookAheadIterator
Foo nextFoo = lookAhead.getNext();
doBetweenFoos(currentFoo, nextFoo);
}
}
Handling of null
values
For situations where it is necessary to provide an Iterator
, but no meaningful Iterator
is available, it might be useful to create an EmptyIterator
. An EmptyIterator
doesn't yield any values, but fulfills the Iterator
contract.
// yields nothing
Iterator<Foo> emptyIterator = new EmptyIterator<>();
For situations where some Iterator
is obtained and passed along, it might be useful to wrap the obtained Iterator
in a NullSaveIterator
. A NullSaveIterator
always fulfills the Iterator
contract, even if it is constructed from a null
Iterator
.
// an iterator that may be null
Iterator<Foo> iterator = ...
// yields every foo from iterator of nothing, if iterator is null
Iterator<Foo> nullSaveIterator = new NullSaveIterator<>(iterator);
For situations where some Iterator
is obtained, it might be useful to wrap the obtained Iterator
in a NullFreeIterator
. A NullFreeIterator
filters out all null
values yielded by the obtained Iterator
.
Iterator<Foo> iterator = ...
// yields every non-null foo from iterator
Iterator<Foo> nullFreeIterator = new NullFreeIterator<>(iterator);
Handling of remove()
operation
This library provides the ProtectedIterator
interface. A ProtectedIterator
is an Iterator
that must throw an UnsupportedOperationException
, if remove()
is called.
This library provides the ProtectingIterator
that takes an existing Iterator
and yields all values yielded by the given Iterator
, but throws a UnsupportedoperationException
, if remove()
is called.
Iterator<Foo> iterator = ...
// yields every foo from iterator, but doesn't allow removing
ProtectingIterator<Foo> protectingIterator = new ProtectingIterator<>(iterator);
This library provides the RemoveHandlerIterator
that takes an existing Iterator
and a Handler
and yields all values yielded by the given Iterator
, but calls the given handler with the last yielded value, instead of calling remove()
on the given Iterator
.
Iterator<Foo> iterator = ...
// yields every foo from iterator, but intercepts removing
Iterator<Foo> removeHandlerIterator = new RemoveHandlerIterator<>(iterator, new Handler<Foo>(){
@Override
public void handle(Foo foo) {
System.out.println(foo + " has been removed"); // some handling
}
});
Iterating over single values
This library provides the ObjectIterator
and OptionalIterator
that take and yield an existing object. An ObjectIterator
always yields the given object, whereas an OptionalIterator
only yields the given object, if it isn't null
.
Foo foo = ...
// yields foo, even if foo is null
Iterator<Foo> objectIterator = new ObjectIterator<>(foo);
// yields foo or nothing, if foo is null
Iterator<Foo> optionalIterator = new OptionalIterator<>(foo);
Iterating over multiple values
This library provides the generic PairIterator
that takes an existing Pair
and yields both elements of the given Pair
:
Pair<Foo> pair = ...
// yields both foos from pair
Iterator<Foo> pairIterator = new PairIterator<>(pair);
This library provides the generic TupleIterator
that takes an existing Tuple
with elements of a similar type and yields both elements of the given Tuple
:
Tuple<Foo, Foo> tuple = ...
// yields both foos from tuple
Iterator<Foo> tupleIterator = new TupleIterator<>(tuple);
This library provides the generic TripleIterator
that takes an existing Triple
with elements of a similar type and yields both elements of the given Triple
:
Triple<Foo, Foo, Foo> triple = ...
// yields all foos from triple
Iterator<Foo> tripleIterator = new TripleIterator<>(triple);
Iterating over primitive arrays
This library provides the following Iterators
that take existing primitive arrays and yield all elements of the given array:
BooleanArrayIterator
ByteArrayIterator
CharacterArrayIterator
DoubleArrayIterator
FloatArrayIterator
IntegerArrayIterator
LongArrayIterator
ShortArrayIterator
boolean[] booleans = ...
// yields every boolean from booleans
Iterator<Boolean> arraytIterator = new BooleanArrayIterator(booleans);
Iterating over non-primitive arrays
This library provides the generic ArrayIterator
that takes an existing array and yields all elements of the given array:
Foo[] foos = ...
// yields every foo from foos
Iterator<Foo> arrayIterator = new ArrayIterator<>(foos);
Iterating over other objects
This library provides the generic EnumerationIterator
that takes an existing Enumeration
and yields every object yielded by the given Enumeration
.
Enumeration<Foo> enumeration = ...
// yields every foo from enumeration
Iterator<Foo> enumerationIterator = new EnumerationIterator<>(enumeration);
This library provides the NodeListIterator
that takes an existing NodeList
and yields every Node
yielded by the given NodeList
.
NodeList nodeList = ...
// yields every node from nodeList
Iterator<Node> nodeListIterator = new NodeListIterator(nodeList);
This library provides the StringTokenizerIterator
that takes an existing StringTokenizer
and yields every string yielded by the given StringTokenizer
.
StringTokenizer tokenizer = ...
// yields every string from tokenizer
Iterator<String> tokenizerIterator = new StringTokenizerIterator(tokenizer);
Iterating infinitely
This library provides the generic InfiniteIterator
that takes a Provider
and infinitely yields provided values.
Provider<Foo> provider = ...
// yields provided foos forever
Iterator<Foo> infiniteIterator = new InfiniteIterator(provider);
Keeping track of iteration index
This library provides the generic IndexedIterator
that takes an existing Iterator
and yield every value yielded by the given Iterator
wrapped in an Entry
whose key is the iteration index of the yielded element.
Iterator<Foo> iterator = ...
// yields an entry for every foo from iterator with
Iterator<Entry<Integer, Foo>> indexedIterator = new IndexedIterator<>(iterator);
Counting up and down
This library provides the CountDownIterator
and CountUpIterator
that take two integer values as bounds and yield every integer value between the given bounds, moving downwards or upwards respectively.
// yields 10, 9, ..., 1, 0
Iterator<Integer> countDownIterator = new CountDownIterator(10, 0);
// yields 0, 1, ..., 9, 10
Iterator<Integer> countUpIterator = new CountUpIterator(0, 10);