(enumerator) {
@Override protected E transform(F from) {
return func.apply(from);
}
};
}
/**
* Converts the elements of a given Iterable to the specified type.
*
* This method is implemented by using deferred execution. The immediate
* return value is an object that stores all the information that is
* required to perform the action. The query represented by this method is
* not executed until the object is enumerated either by calling its
* {@link Enumerable#enumerator} method directly or by using
* {@code for (... in ...)}.
*
*
Since standard Java {@link Collection} objects implement the
* {@link Iterable} interface, the {@code cast} method enables the standard
* query operators to be invoked on collections
* (including {@link java.util.List} and {@link java.util.Set}) by supplying
* the necessary type information. For example, {@link ArrayList} does not
* implement {@link Enumerable}<F>, but you can invoke
*
*
Linq4j.cast(list, Integer.class)
*
* to convert the list of an enumerable that can be queried using the
* standard query operators.
*
*
If an element cannot be cast to type <TResult>, this method will
* throw a {@link ClassCastException}. To obtain only those elements that
* can be cast to type TResult, use the {@link #ofType} method instead.
*
* @see Enumerable#cast(Class)
* @see #ofType
* @see #asEnumerable(Iterable)
*/
public static Enumerable cast(
Iterable source, Class clazz) {
return asEnumerable(source).cast(clazz);
}
/**
* Returns elements of a given {@link Iterable} that are of the specified
* type.
*
* This method is implemented by using deferred execution. The immediate
* return value is an object that stores all the information that is
* required to perform the action. The query represented by this method is
* not executed until the object is enumerated either by calling its
* {@link Enumerable#enumerator} method directly or by using
* {@code for (... in ...)}.
*
*
The {@code ofType} method returns only those elements in source that
* can be cast to type TResult. To instead receive an exception if an
* element cannot be cast to type TResult, use
* {@link #cast(Iterable, Class)}.
*
* Since standard Java {@link Collection} objects implement the
* {@link Iterable} interface, the {@code cast} method enables the standard
* query operators to be invoked on collections
* (including {@link java.util.List} and {@link java.util.Set}) by supplying
* the necessary type information. For example, {@link ArrayList} does not
* implement {@link Enumerable}<F>, but you can invoke
*
*
Linq4j.ofType(list, Integer.class)
*
* to convert the list of an enumerable that can be queried using the
* standard query operators.
*
* @see Enumerable#cast(Class)
* @see #cast
*/
public static Enumerable ofType(
Iterable source, Class clazz) {
return asEnumerable(source).ofType(clazz);
}
/**
* Returns an {@link Enumerable} that has one element.
*
* @param Element type
*
* @return Singleton enumerable
*/
public static Enumerable singletonEnumerable(final T element) {
return new AbstractEnumerable() {
@Override public Enumerator enumerator() {
return singletonEnumerator(element);
}
};
}
/**
* Returns an {@link Enumerator} that has one element.
*
* @param Element type
*
* @return Singleton enumerator
*/
public static Enumerator singletonEnumerator(T element) {
return new SingletonEnumerator<>(element);
}
/**
* Returns an {@link Enumerator} that has one null element.
*
* @param Element type
*
* @return Singleton enumerator
*/
public static Enumerator singletonNullEnumerator() {
return new SingletonNullEnumerator<>();
}
/**
* Returns an {@link Enumerable} that has no elements.
*
* @param Element type
*
* @return Empty enumerable
*/
public static Enumerable emptyEnumerable() {
//noinspection unchecked
return (Enumerable) EMPTY_ENUMERABLE;
}
/**
* Returns an {@link Enumerator} that has no elements.
*
* @param Element type
*
* @return Empty enumerator
*/
public static Enumerator emptyEnumerator() {
//noinspection unchecked
return (Enumerator) EMPTY_ENUMERATOR;
}
/**
* Concatenates two or more {@link Enumerable}s to form a composite
* enumerable that contains the union of their elements.
*
* @param enumerableList List of enumerable objects
* @param Element type
*
* @return Composite enumerator
*/
public static Enumerable concat(
final List> enumerableList) {
return new CompositeEnumerable<>(enumerableList);
}
/**
* Returns an enumerator that is the cartesian product of the given
* enumerators.
*
* For example, given enumerator A that returns {"a", "b", "c"} and
* enumerator B that returns {"x", "y"}, product(List(A, B)) will return
* {List("a", "x"), List("a", "y"),
* List("b", "x"), List("b", "y"),
* List("c", "x"), List("c", "y")}.
*
* Notice that the cardinality of the result is the product of the
* cardinality of the inputs. The enumerators A and B have 3 and 2
* elements respectively, and the result has 3 * 2 = 6 elements.
* This is always the case. In
* particular, if any of the enumerators is empty, the result is empty.
*
* @param enumerators List of enumerators
* @param Element type
*
* @return Enumerator over the cartesian product
*/
public static Enumerator> product(
List> enumerators) {
return new CartesianProductListEnumerator<>(enumerators);
}
/** Returns the cartesian product of an iterable of iterables. */
public static Iterable> product(
final Iterable extends Iterable> iterables) {
return () -> {
final List> enumerators = new ArrayList<>();
for (Iterable iterable : iterables) {
enumerators.add(iterableEnumerator(iterable));
}
return enumeratorIterator(
new CartesianProductListEnumerator<>(enumerators));
};
}
/**
* Returns whether the arguments are equal to each other.
*
* Equivalent to {@link java.util.Objects#equals} in JDK 1.7 and above.
*/
@Deprecated // to be removed before 2.0
public static boolean equals(T t0, T t1) {
return Objects.equals(t0, t1);
}
/**
* Throws {@link NullPointerException} if argument is null, otherwise
* returns argument.
*
* Equivalent to {@link java.util.Objects#requireNonNull} in JDK 1.7 and
* above.
*/
@Deprecated // to be removed before 2.0
public static T requireNonNull(T o) {
if (o == null) {
throw new NullPointerException();
}
return o;
}
/** Closes an iterator, if it can be closed. */
private static void closeIterator(@Nullable Iterator extends T> iterator) {
if (iterator instanceof AutoCloseable) {
try {
((AutoCloseable) iterator).close();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
/** Iterable enumerator.
*
* @param element type */
@SuppressWarnings("unchecked")
static class IterableEnumerator implements Enumerator {
private final Iterable extends T> iterable;
@Nullable Iterator extends T> iterator;
T current;
IterableEnumerator(Iterable extends T> iterable) {
this.iterable = iterable;
iterator = iterable.iterator();
current = (T) DUMMY;
}
@Override public T current() {
if (current == DUMMY) {
throw new NoSuchElementException();
}
return current;
}
@Override public boolean moveNext() {
if (Objects.requireNonNull(iterator, "iterator").hasNext()) {
current = iterator.next();
return true;
}
current = (T) DUMMY;
return false;
}
@Override public void reset() {
iterator = iterable.iterator();
current = (T) DUMMY;
}
@Override public void close() {
final Iterator extends T> iterator1 = this.iterator;
this.iterator = null;
closeIterator(iterator1);
}
}
/** Composite enumerable.
*
* @param element type */
static class CompositeEnumerable extends AbstractEnumerable {
private final List> enumerableList;
CompositeEnumerable(List> enumerableList) {
this.enumerableList = enumerableList;
}
@Override public Enumerator enumerator() {
return new Enumerator() {
// Never null.
Enumerator current = emptyEnumerator();
final Enumerator> enumerableEnumerator = iterableEnumerator(enumerableList);
@Override public E current() {
return current.current();
}
@Override public boolean moveNext() {
for (;;) {
if (current.moveNext()) {
return true;
}
current.close();
if (!enumerableEnumerator.moveNext()) {
current = emptyEnumerator();
return false;
}
current = enumerableEnumerator.current().enumerator();
}
}
@Override public void reset() {
enumerableEnumerator.reset();
current = emptyEnumerator();
}
@Override public void close() {
current.close();
current = emptyEnumerator();
}
};
}
}
/** Iterable enumerable.
*
* @param element type */
static class IterableEnumerable extends AbstractEnumerable2 {
protected final Iterable iterable;
IterableEnumerable(Iterable iterable) {
this.iterable = iterable;
}
@Override public Iterator iterator() {
return iterable.iterator();
}
@Override public boolean any() {
return iterable.iterator().hasNext();
}
}
/** Collection enumerable.
*
* @param element type */
static class CollectionEnumerable extends IterableEnumerable {
CollectionEnumerable(Collection iterable) {
super(iterable);
}
protected Collection getCollection() {
return (Collection) iterable;
}
@Override public int count() {
return getCollection().size();
}
@Override public long longCount() {
return getCollection().size();
}
@SuppressWarnings("argument.type.incompatible")
@Override public boolean contains(T element) {
return getCollection().contains(element);
}
@Override public boolean any() {
return !getCollection().isEmpty();
}
}
/** List enumerable.
*
* @param element type */
static class ListEnumerable extends CollectionEnumerable {
ListEnumerable(List list) {
super(list);
}
@Override public Enumerator enumerator() {
if (iterable instanceof RandomAccess) {
//noinspection unchecked
return new ListEnumerator<>((List) iterable);
}
return super.enumerator();
}
@Override public List toList() {
return (List) iterable;
}
@Override public Enumerable skip(int count) {
final List list = toList();
if (count >= list.size()) {
return Linq4j.emptyEnumerable();
}
return new ListEnumerable<>(list.subList(count, list.size()));
}
@Override public Enumerable take(int count) {
final List list = toList();
if (count >= list.size()) {
return this;
}
return new ListEnumerable<>(list.subList(0, count));
}
@Override public T elementAt(int index) {
return toList().get(index);
}
}
/** Enumerator that returns one element.
*
* @param element type */
private static class SingletonEnumerator implements Enumerator {
final E e;
int i = 0;
SingletonEnumerator(E e) {
this.e = e;
}
@Override public E current() {
return e;
}
@Override public boolean moveNext() {
return i++ == 0;
}
@Override public void reset() {
i = 0;
}
@Override public void close() {
}
}
/** Enumerator that returns one null element.
*
* @param element type */
private static class SingletonNullEnumerator<@Nullable E> implements Enumerator {
int i = 0;
@Override public E current() {
return null;
}
@Override public boolean moveNext() {
return i++ == 0;
}
@Override public void reset() {
i = 0;
}
@Override public void close() {
}
}
/** Iterator that reads from an underlying {@link Enumerator}.
*
* @param element type */
private static class EnumeratorIterator
implements Iterator, AutoCloseable {
private final Enumerator enumerator;
boolean hasNext;
EnumeratorIterator(Enumerator enumerator) {
this.enumerator = enumerator;
hasNext = enumerator.moveNext();
}
@Override public boolean hasNext() {
return hasNext;
}
@Override public T next() {
T t = enumerator.current();
hasNext = enumerator.moveNext();
return t;
}
@Override public void remove() {
throw new UnsupportedOperationException();
}
@Override public void close() {
enumerator.close();
}
}
/** Enumerator optimized for random-access list.
*
* @param element type */
private static class ListEnumerator implements Enumerator {
private final List extends V> list;
int i = -1;
ListEnumerator(List extends V> list) {
this.list = list;
}
@Override public V current() {
return list.get(i);
}
@Override public boolean moveNext() {
return ++i < list.size();
}
@Override public void reset() {
i = -1;
}
@Override public void close() {
}
}
/** Enumerates over the cartesian product of the given lists, returning
* a list for each row.
*
* @param element type */
private static class CartesianProductListEnumerator
extends CartesianProductEnumerator> {
CartesianProductListEnumerator(List> enumerators) {
super(enumerators);
}
@Override public List current() {
return Arrays.asList(elements.clone());
}
}
}