![JAR search and dependency download from the Maven repository](/logo.png)
com.jillesvangurp.iterables.Iterables Maven / Gradle / Ivy
package com.jillesvangurp.iterables;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* Collection of static methods for working with iterators and iterables that allow you to filter, process, etc.
* elements in an Iterable. The methods in this class make it easy to use many of the more primitive functionality
* in this library. You can implement concurrent map reduce logic with just a few lines of code for example.
*/
public class Iterables {
/**
* Wraps an iterator with an iterable so that you may use it in a for loop.
* @param it any iterator
* @return an iterable that may be used with a for loop
*/
public static Iterable toIterable(final Iterator it) {
return new Iterable() {
@Override
public Iterator iterator() {
return it;
}
};
}
public static Iterable toIterable(final T[] array) {
return toIterable(new Iterator() {
int index=0;
@Override
public boolean hasNext() {
return index Iterable filter(Iterable it, Filter filter) {
return new FilteringIterable(it, filter);
}
/**
* @param it
* @param from
* @param to
* @return elements between from and to in the wrapped iterator.
*/
public static Iterable filterRange(Iterable it, final long from, final long to) {
return filter(it, new Filter() {
long count=0;
@Override
public boolean passes(S o) {
long current = count++;
return current >=from && current <=to;
}
});
}
/**
* @param it
* @param to
* @return the elements in the wrapped iterator until element number to
*/
public static Iterable head(Iterable it, final long to) {
return filter(it, new Filter() {
long count=0;
@Override
public boolean passes(S o) {
if (count++ <=to) {
return true;
} else {
throw new PermanentlyFailToPassException();
}
}
});
}
/**
* @param it
* @param from
* @return iterable that iterates the elementents from the 'from'th element in the wrapped iterator.
*/
public static Iterable from(Iterable it, final long from) {
return filter(it, new Filter() {
long count=0;
@Override
public boolean passes(S o) {
long current = count++;
return current >=from;
}
});
}
/**
* Implement a map operation that applies a processor to each element in the wrapped iterator and iterates over the resulting output.
* @param it
* @param processor
* @return iteratable over the output of the processor on the input iterator
*/
public static Iterable map(Iterable it, Processor processor) {
return new ProcessingIterable(it.iterator(), processor);
}
/**
* Compose two or more processors into one.
* @param first transform into intermediate type
* @param last transform intermediate type into output type
* @param extraSteps optional, varargs with extra transformation steps on the output type
* @return a processor that composes the argumentst
*/
@SafeVarargs
public static Processor compose(final Processor first, final Processor last, final Processor...extraSteps) {
return new Processor() {
@Override
public O process(I input) {
O result = last.process(first.process(input));
for (Processor processor : extraSteps) {
result = processor.process(result);
}
return result;
}
};
}
/**
* Process iterable concurrently using the processor. IMPORTANT, you must close the iterable (it implements Closeable) after use otherwise, the process
* may never exit.
* @param input
* @param processor
* @param blockSize
* @param threadPoolSize
* @param queueCapacity
* @return a concurrent processing iterable that will process the input iterable concurrently and offer the output as another iterable.
*/
public static ConcurrentProcessingIterable processConcurrently(Iterable input, Processor processor, int blockSize, int threadPoolSize, int queueCapacity) {
return new ConcurrentProcessingIterable(input, processor, blockSize, threadPoolSize, queueCapacity);
}
/**
* Given a number of iterables, construct a iterable that iterates all of the iterables.
* @param iterables
* @return an iterable that can provide a single iterator for all the elements of the iterables.
*/
public static Iterable compose(final Iterable> iterables) {
return toIterable(new Iterator() {
Iterator> it=iterables.iterator();
Iterator current = null;
V next = null;
@Override
public boolean hasNext() {
if(next != null) {
return true;
} else {
if((current == null || !current.hasNext()) && it.hasNext()) {
while(it.hasNext() && (current == null || !current.hasNext())) {
Iterable nextIt = it.next();
if(nextIt != null) {
current = nextIt.iterator();
}
}
}
if(current !=null && current.hasNext()) {
next = current.next();
return true;
}
}
return false;
}
@Override
public V next() {
if(hasNext()) {
V result = next;
next = null;
return result;
} else {
throw new NoSuchElementException();
}
}
@Override
public void remove() {
throw new UnsupportedOperationException("Remove is not supported");
}
});
}
/**
* Allows you to iterate over objects and cast them to the appropriate type on the fly.
* @param it
* @param clazz
* @return an iterable that casts elements to the specified class.
* @throws ClassCastException if the elements are not castable
*/
public static Iterable castingIterable(Iterable it, Class clazz) {
return map(it, new Processor() {
@SuppressWarnings("unchecked")
@Override
public O process(I input) {
return (O)input;
}});
}
public static long count(Iterable iterable) {
long count = 0;
for(@SuppressWarnings("unused") V e:iterable) {
count++;
}
return count;
}
/**
* Creates an iterator and iterates over it without doing anything thus 'consuming' the iterable. Useful when
* using processing iterables where the side effects are more interesting than the return value of process.
*/
public static void consume(Iterable> it) {
Iterator> iterator = it.iterator();
consume(iterator);
}
/**
*Iterates over an iterator without doing anything with the elements thus 'consuming' the iterator. Useful when
* using processing iterables where the side effects are more interesting than the return value of process.
*/
public static void consume(Iterator> iterator) {
while(iterator.hasNext()) {
iterator.next();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy