spark.debug.Iterables Maven / Gradle / Ivy
package spark.debug;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import com.google.common.base.Optional;
/**
* Provides utility functions for efficiently wrapping Iterable objects.
* Note: Some of these are provided in Guava as well.
*/
public class Iterables {
@FunctionalInterface
public static interface Filter {
/**
* @param item An item.
* @return True if item should be included in the output, false otherwise.
*/
public boolean matches(T item);
}
@FunctionalInterface
public static interface Mapper {
/**
* @param item An item.
* @return The item produced by executing the map function.
*/
public S map(T item);
}
@FunctionalInterface
public static interface Reducer {
public S reduce(S accumulator, T item);
}
/**
* @param input An input iterable.
* @param filter A filtering function.
* @return An iterable that provides a view of input which only contains items matching filter.
*/
public static Iterable filter(Iterable input, Filter filter) {
return new Iterable() {
@Override
public Iterator iterator() {
return new FilterIterator(input.iterator(), filter);
}
};
}
/**
* Implements a filter iterator.
*
* @param Value type.
*/
private static final class FilterIterator implements Iterator {
private final Iterator input;
private final Filter filter;
private boolean hasNext = false;
private T next = null;
public FilterIterator(Iterator input, Filter filter) {
this.input = input;
this.filter = filter;
advance();
}
private void advance() {
while (input.hasNext()) {
hasNext = true;
next = input.next();
if (filter.matches(next)) {
return;
} else {
next = null;
hasNext = false;
}
}
next = null;
hasNext = false;
}
@Override
public boolean hasNext() {
return hasNext;
}
@Override
public T next() {
T value = next;
advance();
return value;
}
}
/**
* @param input An input Iterable.
* @param mapper A map function.
* @return A view of input which is obtained by executing the map function on all values in input.
*/
public static Iterable map(Iterable input, Mapper mapper) {
return new Iterable() {
@Override
public Iterator iterator() {
return new MapIterator(input.iterator(), mapper);
}
};
}
/**
* Implements a map iterator.
*
* @param Original value type.
* @param Mapped value type.
*/
private static final class MapIterator implements Iterator {
private final Iterator input;
private final Mapper mapper;
public MapIterator(Iterator input, Mapper mapper) {
this.input = input;
this.mapper = mapper;
}
@Override
public boolean hasNext() {
return input.hasNext();
}
@Override
public S next() {
return mapper.map(input.next());
}
}
/**
* @param input An input list.
* @param mapper A map function.
* @return The input list of type List (modified in-place from List).
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public static List mapList(List input, Mapper mapper) {
ListIterator iterator = input.listIterator();
while (iterator.hasNext()) {
iterator.set(mapper.map((T) iterator.next()));
}
return (List) input;
}
/**
* @param collection An iterable.
* @param initialValue An initial value.
* @param reducer A reduction function.
* @return The reduced value.
*/
public static S reduce(Iterable collection, S initialValue, Reducer reducer) {
S value = initialValue;
for (T item : collection) {
value = reducer.reduce(value, item);
}
return value;
}
/**
* @param collection An iterable.
* @param filter A filter.
* @return The first item matching the filter (if any).
*/
public static Optional first(Iterable collection, Filter filter) {
for (T item : collection) {
if (filter.matches(item)) {
return Optional.of(item);
}
}
return Optional.absent();
}
/**
* @param collection An iterable (non-empty).
* @return The first item in the given iterable.
*/
public static T first(Iterable collection) {
for (T item : collection) {
return item;
}
throw new IllegalArgumentException("Provided iterable was empty.");
}
}