| /******************************************************************************* |
| * Copyright (c) 2011, 2017 itemis AG (http://www.itemis.eu) and others. |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| *******************************************************************************/ |
| package org.eclipse.xtext.xbase.lib; |
| |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.ListIterator; |
| import java.util.Map; |
| import java.util.NoSuchElementException; |
| import java.util.Set; |
| import java.util.SortedSet; |
| |
| import org.eclipse.xtext.xbase.lib.Functions.Function1; |
| import org.eclipse.xtext.xbase.lib.Functions.Function2; |
| import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; |
| import org.eclipse.xtext.xbase.lib.Procedures.Procedure2; |
| import org.eclipse.xtext.xbase.lib.internal.BooleanFunctionDelegate; |
| import org.eclipse.xtext.xbase.lib.internal.FunctionDelegate; |
| |
| import com.google.common.annotations.Beta; |
| import com.google.common.annotations.GwtCompatible; |
| import com.google.common.annotations.GwtIncompatible; |
| import com.google.common.base.Predicates; |
| import com.google.common.collect.Iterables; |
| import com.google.common.collect.Lists; |
| import com.google.common.collect.Sets; |
| |
| /** |
| * This is an extension library for {@link Iterable iterables}. |
| * |
| * @author Sven Efftinge - Initial contribution and API |
| * @author Sebastian Zarnekow |
| */ |
| @GwtCompatible |
| public class IterableExtensions { |
| |
| /** |
| * <p> |
| * Concatenates two iterables into a single iterable. The returned iterable has an iterator that traverses the |
| * elements in {@code a}, followed by the elements in {@code b}. The resulting iterable is effectivly a view on the |
| * source iterables. That is, the source iterators are not polled until necessary and the result will reflect |
| * changes in the sources. |
| * </p> |
| * <p> |
| * The returned iterable's iterator supports {@code remove()} when the corresponding input iterator supports it. |
| * </p> |
| * |
| * @param a |
| * the first iterable. May not be <code>null</code>. |
| * @param b |
| * the second iterable. May not be <code>null</code>. |
| * @return a combined iterable. Never <code>null</code>. |
| */ |
| @Pure |
| @Inline(value="$3.$4concat($1, $2)", imported=Iterables.class) |
| public static <T> Iterable<T> operator_plus(Iterable<? extends T> a, Iterable<? extends T> b) { |
| return Iterables.concat(a, b); |
| } |
| |
| /** |
| * Finds the first element in the given iterable that fulfills the predicate. If none is found or the iterable is |
| * empty, <code>null</code> is returned. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @param predicate |
| * the predicate. May not be <code>null</code>. |
| * @return the first element in the iterable for which the given predicate returns <code>true</code>, returns |
| * <code>null</code> if no element matches the predicate or the iterable is empty. |
| */ |
| public static <T> T findFirst(Iterable<T> iterable, Function1<? super T, Boolean> predicate) { |
| return IteratorExtensions.findFirst(iterable.iterator(), predicate); |
| } |
| |
| /** |
| * Finds the last element in the given iterable that fulfills the predicate. If none is found or the iterable is |
| * empty, <code>null</code> is returned. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @param predicate |
| * the predicate. May not be <code>null</code>. |
| * @return the last element in the iterable for which the given predicate returns <code>true</code>, returns |
| * <code>null</code> if no element matches the predicate or the iterable is empty. |
| */ |
| public static <T> T findLast(Iterable<T> iterable, Functions.Function1<? super T, Boolean> predicate) { |
| if (predicate == null) |
| throw new NullPointerException("predicate"); |
| if (iterable instanceof List<?>) { |
| List<T> list = (List<T>) iterable; |
| ListIterator<T> iterator = list.listIterator(list.size()); |
| while (iterator.hasPrevious()) { |
| T t = iterator.previous(); |
| if (predicate.apply(t)) |
| return t; |
| } |
| return null; |
| } else { |
| return IteratorExtensions.findLast(iterable.iterator(), predicate); |
| } |
| } |
| |
| /** |
| * Returns the first element in the given iterable or <code>null</code> if empty. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @return the first element in the iterable or <code>null</code>. |
| */ |
| public static <T> T head(Iterable<T> iterable) { |
| return IteratorExtensions.head(iterable.iterator()); |
| } |
| |
| /** |
| * Returns a view on this iterable that contains all the elements except the first. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @return an iterable with all elements except the first. Never <code>null</code>. |
| * @see #drop(Iterable, int) |
| */ |
| public static <T> Iterable<T> tail(final Iterable<T> iterable) { |
| return drop(iterable, 1); |
| } |
| |
| /** |
| * Returns the last element in the given iterable or <code>null</code> if empty. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @return the last element in the iterable or <code>null</code>. |
| */ |
| public static <T> T last(Iterable<T> iterable) { |
| if (iterable instanceof List<?>) { |
| List<T> list = (List<T>) iterable; |
| if (list.isEmpty()) |
| return null; |
| return list.get(list.size() - 1); |
| } else if (iterable instanceof SortedSet) { |
| SortedSet<T> sortedSet = (SortedSet<T>) iterable; |
| if (sortedSet.isEmpty()) |
| return null; |
| return sortedSet.last(); |
| } else { |
| return IteratorExtensions.last(iterable.iterator()); |
| } |
| } |
| |
| /** |
| * Returns a view on this iterable that provides at most the first <code>count</code> entries. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @param count |
| * the number of elements that should be returned at most. |
| * @return an iterable with <code>count</code> elements. Never <code>null</code>. |
| * @throws IllegalArgumentException |
| * if <code>count</code> is negative. |
| */ |
| public static <T> Iterable<T> take(final Iterable<T> iterable, final int count) { |
| if (iterable == null) |
| throw new NullPointerException("iterable"); |
| if (count < 0) |
| throw new IllegalArgumentException("Cannot take a negative number of elements. Argument 'count' was: " |
| + count); |
| if (count == 0) |
| return Collections.emptyList(); |
| return new Iterable<T>() { |
| @Override |
| public Iterator<T> iterator() { |
| return IteratorExtensions.take(iterable.iterator(), count); |
| } |
| }; |
| } |
| |
| /** |
| * Returns a view on this iterable that provides all elements except the first <code>count</code> entries. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @param count |
| * the number of elements that should be dropped. |
| * @return an iterable without the first <code>count</code> elements. Never <code>null</code>. |
| * @throws IllegalArgumentException |
| * if <code>count</code> is negative. |
| */ |
| @Pure |
| public static <T> Iterable<T> drop(final Iterable<T> iterable, final int count) { |
| if (iterable == null) |
| throw new NullPointerException("iterable"); |
| if (count == 0) |
| return iterable; |
| if (count < 0) |
| throw new IllegalArgumentException("Cannot drop a negative number of elements. Argument 'count' was: " |
| + count); |
| return new Iterable<T>() { |
| @Override |
| public Iterator<T> iterator() { |
| return IteratorExtensions.drop(iterable.iterator(), count); |
| } |
| }; |
| } |
| |
| /** |
| * Returns {@code true} if one or more elements in {@code iterable} satisfy the predicate. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @param predicate |
| * the predicate. May not be <code>null</code>. |
| * @return <code>true</code> if one or more elements in {@code iterable} satisfy the predicate. |
| */ |
| public static <T> boolean exists(Iterable<T> iterable, Function1<? super T, Boolean> predicate) { |
| return IteratorExtensions.exists(iterable.iterator(), predicate); |
| } |
| |
| /** |
| * Returns {@code true} if every element in {@code iterable} satisfies the predicate. If {@code iterable} is empty, |
| * {@code true} is returned. In other words, <code>false</code> is returned if at least one element fails to fulfill |
| * the predicate. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @param predicate |
| * the predicate. May not be <code>null</code>. |
| * @return <code>true</code> if every element in {@code iterable} satisfies the predicate and also if there is no element. |
| */ |
| public static <T> boolean forall(Iterable<T> iterable, Function1<? super T, Boolean> predicate) { |
| return IteratorExtensions.forall(iterable.iterator(), predicate); |
| } |
| |
| /** |
| * Returns the elements of {@code unfiltered} that satisfy a predicate. The resulting iterable's iterator does not |
| * support {@code remove()}. The returned iterable is a view on the original elements. Changes in the unfiltered |
| * original are reflected in the view. |
| * |
| * @param unfiltered |
| * the unfiltered iterable. May not be <code>null</code>. |
| * @param predicate |
| * the predicate. May not be <code>null</code>. |
| * @return an iterable that contains only the elements that fulfill the predicate. Never <code>null</code>. |
| */ |
| @Pure |
| public static <T> Iterable<T> filter(Iterable<T> unfiltered, Function1<? super T, Boolean> predicate) { |
| return Iterables.filter(unfiltered, new BooleanFunctionDelegate<T>(predicate)); |
| } |
| |
| /** |
| * Returns the elements of {@code unfiltered} that do not satisfy a predicate. The resulting iterable's iterator does not |
| * support {@code remove()}. The returned iterable is a view on the original elements. Changes in the unfiltered |
| * original are reflected in the view. |
| * |
| * @param unfiltered |
| * the unfiltered iterable. May not be <code>null</code>. |
| * @param predicate |
| * the predicate. May not be <code>null</code>. |
| * @return an iterable that contains only the elements that do not fulfill the predicate. Never <code>null</code>. |
| * |
| * @since 2.11 |
| */ |
| @Pure |
| public static <T> Iterable<T> reject(Iterable<T> unfiltered, Function1<? super T, Boolean> predicate) { |
| return Iterables.filter(unfiltered, Predicates.not(new BooleanFunctionDelegate<T>(predicate))); |
| } |
| |
| /** |
| * Returns the elements of {@code unfiltered} that are not instanceof {@code type}. The resulting iterable's iterator does not |
| * support {@code remove()}. The returned iterable is a view on the original elements. Changes in the unfiltered |
| * original are reflected in the view. |
| * |
| * @param unfiltered |
| * the unfiltered iterable. May not be <code>null</code>. |
| * @param type |
| * the type of elements undesired. May not be <code>null</code>. |
| * @return an iterable that contains only the elements that are not instances of {@code type}. Never <code>null</code>. |
| * Note that the elements of the iterable can be null as null is an instance of nothing. |
| * |
| * @since 2.15 |
| */ |
| @GwtIncompatible("Class.isInstance") |
| @Pure |
| public static <T> Iterable<T> reject(Iterable<T> unfiltered, Class<?> type) { |
| return filter(unfiltered, (t) -> !type.isInstance(t)); |
| } |
| |
| /** |
| * Returns all instances of class {@code type} in {@code unfiltered}. The returned iterable has elements whose class |
| * is {@code type} or a subclass of {@code type}. The returned iterable's iterator does not support {@code remove()} |
| * . The returned iterable is a view on the original elements. Changes in the unfiltered original are reflected in |
| * the view. |
| * |
| * @param unfiltered |
| * the unfiltered iterable. May not be <code>null</code>. |
| * @param type |
| * the type of elements desired |
| * @return an unmodifiable iterable containing all elements of the original iterable that were of the requested |
| * type. Never <code>null</code>. |
| */ |
| @GwtIncompatible("Class.isInstance") |
| @Pure |
| @Inline(value="$3.$4filter($1, $2)", imported=Iterables.class) |
| public static <T> Iterable<T> filter(Iterable<?> unfiltered, Class<T> type) { |
| return Iterables.filter(unfiltered, type); |
| } |
| |
| /** |
| * Returns a new iterable filtering any null references. |
| * |
| * @param unfiltered |
| * the unfiltered iterable. May not be <code>null</code>. |
| * @return an unmodifiable iterable containing all elements of the original iterable without any <code>null</code> references. Never <code>null</code>. |
| */ |
| @Pure |
| public static <T> Iterable<T> filterNull(Iterable<T> unfiltered) { |
| return Iterables.filter(unfiltered, Predicates.notNull()); |
| } |
| |
| /** |
| * Returns an iterable that performs the given {@code transformation} for each element of {@code original} when |
| * requested. The mapping is done lazily. That is, subsequent iterations of the elements in the iterable will |
| * repeatedly apply the transformation. |
| * <p> |
| * The returned iterable's iterator supports {@code remove()} if the provided iterator does. After a successful |
| * {@code remove()} call, {@code original} no longer contains the corresponding element. |
| * </p> |
| * |
| * @param original |
| * the original iterable. May not be <code>null</code>. |
| * @param transformation |
| * the transformation. May not be <code>null</code>. |
| * @return an iterable that provides the result of the transformation. Never <code>null</code>. |
| */ |
| @Pure |
| public static <T, R> Iterable<R> map(Iterable<T> original, Function1<? super T, ? extends R> transformation) { |
| return Iterables.transform(original, new FunctionDelegate<T, R>(transformation)); |
| } |
| |
| /** |
| * Returns an iterable that performs the given {@code transformation} for each element of {@code original} when |
| * requested. The mapping is done lazily. That is, subsequent iterations of the elements in the iterable will |
| * repeatedly apply the transformation. |
| * <p> |
| * The transformation maps each element to an iterable, and all resulting iterables are combined to a single iterable. |
| * Effectively a combination of {@link #map(Iterable, Functions.Function1)} and {@link #flatten(Iterable)} is performed. |
| * </p> |
| * <p> |
| * The returned iterable's iterator <i>does not support {@code remove()}</i> in contrast to {@link #map(Iterable, Functions.Function1)}. |
| * </p> |
| * |
| * @param original |
| * the original iterable. May not be <code>null</code>. |
| * @param transformation |
| * the transformation. May not be <code>null</code> and must not yield <code>null</code>. |
| * @return an iterable that provides the result of the transformation. Never <code>null</code>. |
| * |
| * @since 2.13 |
| */ |
| @Pure |
| public static <T, R> Iterable<R> flatMap(Iterable<T> original, Function1<? super T, ? extends Iterable<R>> transformation) { |
| return flatten(map(original, transformation)); |
| } |
| |
| /** |
| * Combines multiple iterables into a single iterable. The returned iterable has an iterator that traverses the |
| * elements of each iterable in {@code inputs}. The input iterators are not polled until necessary. |
| * |
| * <p> |
| * The returned iterable's iterator supports {@code remove()} when the corresponding input iterator supports it. The |
| * methods of the returned iterable may throw {@code NullPointerException} if any of the input iterators are null. |
| * </p> |
| * |
| * @param inputs |
| * the to be flattened iterables. May not be <code>null</code>. |
| * @return an iterable that provides the concatenated values of the input elements. Never <code>null</code>. |
| */ |
| @Inline(value="$2.$3concat($1)", imported=Iterables.class) |
| public static <T> Iterable<T> flatten(Iterable<? extends Iterable<? extends T>> inputs) { |
| return Iterables.concat(inputs); |
| } |
| |
| /** |
| * Applies {@code procedure} for each element of the given iterable. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @param procedure |
| * the procedure. May not be <code>null</code>. |
| */ |
| public static <T> void forEach(Iterable<T> iterable, Procedure1<? super T> procedure) { |
| IteratorExtensions.forEach(iterable.iterator(), procedure); |
| } |
| |
| /** |
| * Applies {@code procedure} for each element of the given iterable. |
| * The procedure takes the element and a loop counter. If the counter would overflow, {@link Integer#MAX_VALUE} |
| * is returned for all subsequent elements. The first element is at index zero. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @param procedure |
| * the procedure. May not be <code>null</code>. |
| * @since 2.3 |
| */ |
| public static <T> void forEach(Iterable<T> iterable, Procedure2<? super T, ? super Integer> procedure) { |
| IteratorExtensions.forEach(iterable.iterator(), procedure); |
| } |
| |
| /** |
| * Returns the concatenated string representation of the elements in the given iterable. No delimiter is used. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @return the string representation of the iterable's elements. Never <code>null</code>. |
| * @see #join(Iterable, CharSequence, org.eclipse.xtext.xbase.lib.Functions.Function1) |
| */ |
| public static String join(Iterable<?> iterable) { |
| return IteratorExtensions.join(iterable.iterator()); |
| } |
| |
| /** |
| * Returns the concatenated string representation of the elements in the given iterable. The {@code separator} is |
| * used to between each pair of entries in the input. The string <code>null</code> is used for <code>null</code> |
| * entries in the input. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @param separator |
| * the separator. May not be <code>null</code>. |
| * @return the string representation of the iterable's elements. Never <code>null</code>. |
| * @see #join(Iterable, CharSequence, org.eclipse.xtext.xbase.lib.Functions.Function1) |
| */ |
| public static String join(Iterable<?> iterable, CharSequence separator) { |
| return IteratorExtensions.join(iterable.iterator(), separator); |
| } |
| |
| /** |
| * Returns the concatenated string representation of the elements in the given iterable. The {@code function} is |
| * used to compute the string for each element. The {@code separator} is used to between each pair of entries in the |
| * input. The string <code>null</code> is used if the function yields <code>null</code> as the string representation |
| * for an entry. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @param separator |
| * the separator. May not be <code>null</code>. |
| * @param function |
| * the function that is used to compute the string representation of a single element. May not be |
| * <code>null</code>. |
| * @return the string representation of the iterable's elements. Never <code>null</code>. |
| */ |
| public static <T> String join(Iterable<T> iterable, CharSequence separator, |
| Functions.Function1<? super T, ? extends CharSequence> function) { |
| return IteratorExtensions.join(iterable.iterator(), separator, function); |
| } |
| |
| /** |
| * Returns the concatenated string representation of the elements in the given iterable. The {@code function} is |
| * used to compute the string for each element. The {@code separator} is used to between each pair of entries in the |
| * input. The string <code>null</code> is used if the function yields <code>null</code> as the string representation |
| * for an entry. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @param before |
| * prepends the resulting string if the iterable contains at least one element. May be <code>null</code> which is equivalent to passing an empty string. |
| * @param separator |
| * the separator. May be <code>null</code> which is equivalent to passing an empty string. |
| * @param after |
| * appended to the resulting string if the iterable contain at least one element. May be <code>null</code> which is equivalent to passing an empty string. |
| * @param function |
| * the function that is used to compute the string representation of a single element. May not be |
| * <code>null</code>. |
| * @return the string representation of the iterable's elements. Never <code>null</code>. |
| */ |
| public static <T> String join(Iterable<T> iterable, CharSequence before, CharSequence separator, CharSequence after, |
| Functions.Function1<? super T, ? extends CharSequence> function) { |
| return IteratorExtensions.join(iterable.iterator(), before, separator, after, function); |
| } |
| |
| /** |
| * Determines whether two iterables contain equal elements in the same order. More specifically, this method returns |
| * {@code true} if {@code iterable} and {@code other} contain the same number of elements and every element of |
| * {@code iterable} is equal to the corresponding element of {@code other}. |
| * |
| * @param iterable |
| * an iterable. May not be <code>null</code>. |
| * @param other |
| * an iterable. May not be <code>null</code>. |
| * @return <code>true</code> if the two iterables contain equal elements in the same order. |
| */ |
| public static boolean elementsEqual(Iterable<?> iterable, Iterable<?> other) { |
| return Iterables.elementsEqual(iterable, other); |
| } |
| |
| /** |
| * Determines if the given iterable is <code>null</code> or contains no elements. |
| * |
| * @param iterable |
| * the to-be-queried iterable. May be <code>null</code>. |
| * @return {@code true} if the iterable is <code>null</code> or contains no elements |
| */ |
| public static boolean isNullOrEmpty(Iterable<?> iterable) { |
| return iterable == null || isEmpty(iterable); |
| } |
| |
| /** |
| * Determines if the given iterable contains no elements. |
| * |
| * @param iterable |
| * the to-be-queried iterable. May not be <code>null</code>. |
| * @return {@code true} if the iterable contains no elements |
| * @see #isNullOrEmpty(Iterable) |
| */ |
| public static boolean isEmpty(Iterable<?> iterable) { |
| if (iterable instanceof Collection<?>) |
| return ((Collection<?>) iterable).isEmpty(); |
| return !iterable.iterator().hasNext(); |
| } |
| |
| /** |
| * Returns the number of elements in {@code iterable}. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @return the number of elements in {@code iterable}. |
| */ |
| public static int size(Iterable<?> iterable) { |
| return Iterables.size(iterable); |
| } |
| |
| /** |
| * <p> |
| * Applies the combinator {@code function} to all elements of the iterable in turn. |
| * </p> |
| * <p> |
| * One of the function parameters is an element of the iterable, and the other is the result of previous application |
| * of the function. The seed of the operation is the first element in the iterable. The second value is computed by |
| * applying the function to the seed together with the second element of the iterable. The third value is computed |
| * from the previous result together with the third element and so on. In other words, the previous result of each |
| * step is taken and passed together with the next element to the combinator function. |
| * </p> |
| * <p> |
| * If the iterable is empty, <code>null</code> is returned. |
| * </p> |
| * <p> |
| * More formally, given an iterable {@code [a, b, c, d]} and a function {@code f}, the result of {@code reduce} is |
| * <code>f(f(f(a, b), c), d)</code> |
| * </p> |
| * |
| * @param iterable |
| * the to-be-reduced iterable. May not be <code>null</code>. |
| * @param function |
| * the combinator function. May not be <code>null</code>. |
| * @return the last result of the applied combinator function or <code>null</code> for the empty input. |
| */ |
| public static <T> T reduce(Iterable<? extends T> iterable, Function2<? super T, ? super T, ? extends T> function) { |
| return IteratorExtensions.reduce(iterable.iterator(), function); |
| } |
| |
| /** |
| * <p> |
| * Applies the combinator {@code function} to all elements of the iterable in turn and uses {@code seed} as the |
| * start value. |
| * </p> |
| * <p> |
| * One of the function parameters is an element of the iterable, and the other is the result of previous application |
| * of the function. The seed of the operation is explicitly passed to |
| * {@link #fold(Iterable, Object, org.eclipse.xtext.xbase.lib.Functions.Function2) fold}. The first computed value |
| * is the result of the applied function for {@code seed} and the first element of the iterable. This intermediate |
| * result together with the second element of the iterable produced the next result and so on. |
| * </p> |
| * <p> |
| * {@link #fold(Iterable, Object, org.eclipse.xtext.xbase.lib.Functions.Function2) fold} is similar to |
| * {@link #reduce(Iterable, org.eclipse.xtext.xbase.lib.Functions.Function2) reduce} but allows a {@code seed} value |
| * and the combinator {@code function} may be asymmetric. It takes {@code T and R} and returns {@code R}. |
| * <p> |
| * If the iterable is empty, <code>seed</code> is returned. |
| * </p> |
| * <p> |
| * More formally, given an iterable {@code [a, b, c, d]}, a seed {@code initial} and a function {@code f}, the |
| * result of {@code fold} is <code>f(f(f(f(initial, a), b), c), d)</code> |
| * </p> |
| * |
| * @param iterable |
| * the to-be-folded iterable. May not be <code>null</code>. |
| * @param seed |
| * the initial value. May be <code>null</code>. |
| * @param function |
| * the combinator function. May not be <code>null</code>. |
| * @return the last result of the applied combinator function or <code>seed</code> for the empty input. |
| */ |
| public static <T, R> R fold(Iterable<T> iterable, R seed, Function2<? super R, ? super T, ? extends R> function) { |
| return IteratorExtensions.fold(iterable.iterator(), seed, function); |
| } |
| |
| /** |
| * Returns a list that contains all the entries of the given iterable in the same order. If the iterable is of type |
| * {@link List}, itself is returned. Therefore an unchecked cast is performed. |
| * In all other cases, the result list is a copy of the iterable. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @return a list with the same entries as the given iterable. May be the same as the given iterable iff it |
| * implements {@link List}, otherwise a copy is returned. Never <code>null</code>. |
| */ |
| @Beta |
| public static <T> List<T> toList(Iterable<T> iterable) { |
| if (iterable instanceof List<?>) { |
| List<T> result = (List<T>) iterable; |
| return result; |
| } |
| return Lists.newArrayList(iterable); |
| } |
| |
| /** |
| * Returns a set that contains all the unique entries of the given iterable in the order of their appearance. If the |
| * iterable is of type {@link Set}, itself is returned. Therefore an unchecked cast is performed. |
| * In all other cases, the result set is a copy of the iterable with stable order. |
| * |
| * @param iterable |
| * the iterable. May not be <code>null</code>. |
| * @return a set with the unique entries of the given iterable. May be the same as the given iterable iff it |
| * implements {@link Set}, otherwise a copy is returned. Never <code>null</code>. |
| */ |
| @Beta |
| public static <T> Set<T> toSet(Iterable<T> iterable) { |
| if (iterable instanceof Set<?>) { |
| Set<T> result = (Set<T>) iterable; |
| return result; |
| } |
| return Sets.newLinkedHashSet(iterable); |
| } |
| |
| /** |
| * Returns a map for which the {@link Map#values} are computed by the given function, and each key is an element in |
| * the given {@code keys}. If the iterable contains equal keys more than once, the last one will be contained in the |
| * map. The map is computed eagerly. That is, subsequent changes in the keys are not reflected by the map. |
| * |
| * @param keys |
| * the keys to use when constructing the {@code Map}. May not be <code>null</code>. |
| * @param computeValues |
| * the function used to produce the values for each key. May not be <code>null</code>. |
| * @return a map mapping each entry in the given iterable to the corresponding result when evaluating the function |
| * {@code computeValues}. |
| */ |
| public static <K, V> Map<K, V> toInvertedMap(Iterable<? extends K> keys, Function1<? super K, V> computeValues) { |
| return IteratorExtensions.toInvertedMap(keys.iterator(), computeValues); |
| } |
| |
| /** |
| * Returns a map for which the {@link Map#values} are the given elements in the given order, and each key is the |
| * product of invoking a supplied function {@code computeKeys} on its corresponding value. If the function produces |
| * the same key for different values, the last one will be contained in the map. |
| * |
| * @param values |
| * the values to use when constructing the {@code Map}. May not be <code>null</code>. |
| * @param computeKeys |
| * the function used to produce the key for each value. May not be <code>null</code>. |
| * @return a map mapping the result of evaluating the function {@code keyFunction} on each value in the input |
| * collection to that value |
| */ |
| public static <K, V> Map<K, V> toMap(Iterable<? extends V> values, Function1<? super V, K> computeKeys) { |
| return IteratorExtensions.toMap(values.iterator(), computeKeys); |
| } |
| |
| |
| /** |
| * Returns a map for which the {@link Map#values} are the product of invoking supplied function {@code computeValues} |
| * on input iterable elements, and each key is the product of invoking a supplied function {@code computeKeys} on same elements. |
| * If the function produces the same key for different values, the last one will be contained in the map. |
| * |
| * @param inputs |
| * the elements to use when constructing the {@code Map}. May not be <code>null</code>. |
| * @param computeKeys |
| * the function used to produce the key for each value. May not be <code>null</code>. |
| * @param computeValues |
| * the function used to produce the values for each key. May not be <code>null</code>. |
| * @return a map mapping the result of evaluating the functions {@code keyFunction} and {@code computeValues} on each value in the input |
| * iterator to that value |
| */ |
| public static <T, K, V> Map<K, V> toMap(Iterable<? extends T> inputs, Function1<? super T, K> computeKeys, Function1<? super T, V> computeValues) { |
| return IteratorExtensions.toMap(inputs.iterator(),computeKeys,computeValues); |
| } |
| |
| |
| /** |
| * Returns a map for which the {@link Map#values} is a collection of lists, where the elements in the list will |
| * appear in the order as they appeared in the iterable. Each key is the product of invoking the supplied |
| * function {@code computeKeys} on its corresponding value. So a key of that map groups a list of values for |
| * which the function produced exactly that key. |
| * |
| * @param values |
| * the values to use when constructing the {@code Map}. May not be <code>null</code>. |
| * @param computeKeys |
| * the function used to produce the key for each value. May not be <code>null</code>. |
| * @return a map mapping the result of evaluating the function {@code keyFunction} on each value in the input |
| * iterable to that value. As there can be more than one value mapped by a key, the mapping result is is a |
| * list of values. |
| * @since 2.7 |
| */ |
| public static <K, V> Map<K, List<V>> groupBy(Iterable<? extends V> values, |
| Function1<? super V, ? extends K> computeKeys) { |
| return IteratorExtensions.groupBy(values.iterator(), computeKeys); |
| } |
| |
| /** |
| * Creates a sorted list that contains the items of the given iterable. The resulting list is in ascending order, |
| * according to the natural ordering of the elements in the iterable. |
| * |
| * @param iterable |
| * the items to be sorted. May not be <code>null</code>. |
| * @return a sorted list as a shallow copy of the given iterable. |
| * @see Collections#sort(List) |
| * @see #sort(Iterable, Comparator) |
| * @see #sortBy(Iterable, org.eclipse.xtext.xbase.lib.Functions.Function1) |
| * @see ListExtensions#sortInplace(List) |
| */ |
| public static <T extends Comparable<? super T>> List<T> sort(Iterable<T> iterable) { |
| List<T> asList = Lists.newArrayList(iterable); |
| if (iterable instanceof SortedSet<?>) { |
| if (((SortedSet<T>) iterable).comparator() == null) { |
| return asList; |
| } |
| } |
| return ListExtensions.sortInplace(asList); |
| } |
| |
| /** |
| * This method is deprecated in favor of {@link #sortWith(Iterable, Comparator)}. |
| * |
| * Creates a sorted list that contains the items of the given iterable. The resulting list is sorted according to |
| * the order induced by the specified comparator. |
| * |
| * @param iterable |
| * the items to be sorted. May not be <code>null</code>. |
| * @param comparator |
| * the comparator to be used. May be <code>null</code> to indicate that the natural ordering of the |
| * elements should be used. |
| * @return a sorted list as a shallow copy of the given iterable. |
| * @see IterableExtensions#sortWith(Iterable, Comparator) |
| * @deprecated Use {@link #sortWith(Iterable, Comparator)} instead. |
| */ |
| @Deprecated |
| @Inline(value="$3.$4sortWith($1, $2)", imported=IterableExtensions.class) |
| public static <T> List<T> sort(Iterable<T> iterable, Comparator<? super T> comparator) { |
| return sortWith(iterable, comparator); |
| } |
| |
| /** |
| * Creates a sorted list that contains the items of the given iterable. The resulting list is sorted according to |
| * the order induced by the specified comparator. |
| * |
| * @param iterable |
| * the items to be sorted. May not be <code>null</code>. |
| * @param comparator |
| * the comparator to be used. May be <code>null</code> to indicate that the natural ordering of the |
| * elements should be used. |
| * @return a sorted list as a shallow copy of the given iterable. |
| * @see Collections#sort(List, Comparator) |
| * @see #sort(Iterable) |
| * @see #sortBy(Iterable, org.eclipse.xtext.xbase.lib.Functions.Function1) |
| * @see ListExtensions#sortInplace(List, Comparator) |
| * @since 2.7 |
| */ |
| public static <T> List<T> sortWith(Iterable<T> iterable, Comparator<? super T> comparator) { |
| return ListExtensions.sortInplace(Lists.newArrayList(iterable), comparator); |
| } |
| |
| /** |
| * Creates a sorted list that contains the items of the given iterable. The resulting list is sorted according to |
| * the order induced by applying a key function to each element which yields a comparable criteria. |
| * |
| * @param iterable |
| * the elements to be sorted. May not be <code>null</code>. |
| * @param key |
| * the key function to-be-used. May not be <code>null</code>. |
| * @return a sorted list as a shallow copy of the given iterable. |
| * @see #sort(Iterable) |
| * @see #sort(Iterable, Comparator) |
| * @see ListExtensions#sortInplaceBy(List, org.eclipse.xtext.xbase.lib.Functions.Function1) |
| */ |
| public static <T, C extends Comparable<? super C>> List<T> sortBy(Iterable<T> iterable, |
| final Functions.Function1<? super T, C> key) { |
| return ListExtensions.sortInplaceBy(Lists.newArrayList(iterable), key); |
| } |
| |
| |
| |
| /** |
| * Returns an Iterable containing all elements starting from the head of the source up to and excluding the first |
| * element that violates the predicate The resulting Iterable is a lazily computed view, so any modifications to the |
| * underlying Iterables will be reflected on subsequent iterations. The result's Iterator does not support |
| * {@link Iterator#remove()} |
| * |
| * @param iterable |
| * the elements from which to take. May not be <code>null</code>. |
| * @param predicate |
| * the predicate which decides whether to keep taking elements. May not be <code>null</code>. |
| * @return the taken elements |
| * @since 2.7 |
| */ |
| public static <T> Iterable<T> takeWhile(final Iterable<? extends T> iterable, final Function1<? super T, Boolean> predicate) { |
| if (iterable == null) |
| throw new NullPointerException("iterable"); |
| if (predicate == null) |
| throw new NullPointerException("predicate"); |
| return new Iterable<T>() { |
| @Override |
| public Iterator<T> iterator() { |
| return IteratorExtensions.takeWhile(iterable.iterator(), predicate); |
| } |
| }; |
| } |
| |
| /** |
| * Returns an Iterable containing all elements starting from the first element for which the drop-predicate returned |
| * false. The resulting Iterable is a lazily computed view, so any modifications to the underlying Iterables will be |
| * reflected on subsequent iterations. The result's Iterator does not support {@link Iterator#remove()} |
| * |
| * @param iterable |
| * the elements from which to drop. May not be <code>null</code>. |
| * @param predicate |
| * the predicate which decides whether to keep dropping elements. May not be <code>null</code>. |
| * @return the remaining elements after dropping |
| * @since 2.7 |
| */ |
| public static <T> Iterable<T> dropWhile(final Iterable<? extends T> iterable, final Function1<? super T, Boolean> predicate) { |
| if (iterable == null) |
| throw new NullPointerException("iterable"); |
| if (predicate == null) |
| throw new NullPointerException("predicate"); |
| return new Iterable<T>() { |
| @Override |
| public Iterator<T> iterator() { |
| return IteratorExtensions.dropWhile(iterable.iterator(), predicate); |
| } |
| }; |
| } |
| |
| /** |
| * Returns an Iterable of Pairs where the nth pair is created by taking the nth element of the source as the value |
| * its 0-based index as the key. E.g. <code>zipWitIndex(#["a", "b", "c"]) == #[(0, "a"), (1, "b"), (2, "c")]</code> |
| * |
| * If the index would overflow, {@link Integer#MAX_VALUE} is returned for all subsequent elements. |
| * |
| * The resulting Iterable is a lazily computed view, so any modifications to the underlying Iterable will be |
| * reflected on iteration. The result's Iterator does not support {@link Iterator#remove()} |
| * |
| * @param iterable |
| * the elements. May not be <code>null</code>. |
| * @return the zipped result |
| * @since 2.7 |
| */ |
| public static <A> Iterable<Pair<Integer, A>> indexed(final Iterable<? extends A> iterable) { |
| if (iterable == null) |
| throw new NullPointerException("iterable"); |
| return new Iterable<Pair<Integer, A>>() { |
| @Override |
| public Iterator<Pair<Integer, A>> iterator() { |
| return IteratorExtensions.indexed(iterable.iterator()); |
| } |
| }; |
| } |
| |
| /** |
| * Finds the minimum of the given elements according to their natural ordering. If there are several mimina, the |
| * first one will be returned. |
| * |
| * @param iterable |
| * the mutually comparable elements. May not be <code>null</code>. |
| * @return the minimum |
| * @throws NoSuchElementException |
| * if the iterable is empty |
| * @since 2.7 |
| */ |
| public static <T extends Comparable<? super T>> T min(final Iterable<T> iterable) { |
| if (iterable instanceof SortedSet<?>) { |
| SortedSet<T> asSet = (SortedSet<T>) iterable; |
| // only use the set-semantic if we can be absolutely sure that the set uses the natural order |
| if (asSet.comparator() == null) |
| return asSet.first(); |
| } |
| return IteratorExtensions.min(iterable.iterator()); |
| } |
| |
| /** |
| * Finds the element that yields the minimum value when passed to <code>compareBy</code>. If there are several |
| * minima, the first one will be returned. |
| * |
| * @param iterable |
| * the elements to find the minimum of. May not be <code>null</code>. |
| * @param compareBy |
| * a function that returns a comparable characteristic to compare the elements by. May not be <code>null</code>. |
| * @return the minimum |
| * @throws NoSuchElementException |
| * if the iterable is empty |
| * @since 2.7 |
| */ |
| public static <T, C extends Comparable<? super C>> T minBy(final Iterable<T> iterable, |
| final Function1<? super T, C> compareBy) { |
| return IteratorExtensions.minBy(iterable.iterator(), compareBy); |
| } |
| |
| /** |
| * Finds the mininmum element according to <code>comparator</code>. If there are several minima, the first one will |
| * be returned. |
| * |
| * @param iterable |
| * the elements to find the minimum of. May not be <code>null</code>. |
| * @param comparator |
| * the comparison function. May not be <code>null</code>. |
| * @return the minimum |
| * @throws NoSuchElementException |
| * if the iterable is empty |
| * @since 2.7 |
| */ |
| public static <T> T min(final Iterable<T> iterable, Comparator<? super T> comparator) { |
| return IteratorExtensions.min(iterable.iterator(), comparator); |
| } |
| |
| /** |
| * Finds the maximum of the elements according to their natural ordering. If there are several maxima, the first one |
| * will be returned. |
| * |
| * @param iterable |
| * the mutually comparable elements. May not be <code>null</code>. |
| * @return the maximum |
| * @throws NoSuchElementException |
| * if the iterable is empty |
| * @since 2.7 |
| */ |
| public static <T extends Comparable<? super T>> T max(final Iterable<T> iterable) { |
| // cannot special-case for SortedSet since we want to find the first one that is a maximum |
| // where Set.last would return the last of the seemingly equal maximum elements |
| return IteratorExtensions.max(iterable.iterator()); |
| } |
| |
| /** |
| * Finds the element that yields the maximum value when passed to <code>compareBy</code> If there are several |
| * maxima, the first one will be returned. |
| * |
| * @param iterable |
| * the elements to find the maximum of. May not be <code>null</code>. |
| * @param compareBy |
| * a function that returns a comparable characteristic to compare the elements by. May not be <code>null</code>. |
| * @return the maximum |
| * @throws NoSuchElementException |
| * if the iterable is empty |
| * @since 2.7 |
| */ |
| public static <T, C extends Comparable<? super C>> T maxBy(final Iterable<T> iterable, |
| final Function1<? super T, C> compareBy) { |
| return IteratorExtensions.maxBy(iterable.iterator(), compareBy); |
| } |
| |
| /** |
| * Finds the maximum element according to <code>comparator</code>. If there are several maxima, the first one will |
| * be returned. |
| * |
| * @param iterable |
| * the elements to find the maximum of. May not be <code>null</code>. |
| * @param comparator |
| * the comparison function. May not be <code>null</code>. |
| * @return the maximum |
| * @throws NoSuchElementException |
| * if the iterable is empty |
| * @since 2.7 |
| */ |
| public static <T> T max(final Iterable<T> iterable, Comparator<? super T> comparator) { |
| return IteratorExtensions.max(iterable.iterator(), comparator); |
| } |
| |
| /** |
| * Returns <tt>true</tt> if this Iterable contains the specified element. |
| * More formally, returns <tt>true</tt> if and only if this Iterable contains |
| * at least one element <tt>e</tt> such that |
| * <tt>(o==null ? e==null : o.equals(e))</tt>. |
| * |
| * @param iterable |
| * the elements to test |
| * @param o |
| * element whose presence in the Iterable is to be tested |
| * @return <tt>true</tt> if this Iterable contains the specified element |
| */ |
| public static boolean contains(Iterable<?> iterable, Object o) { |
| if (iterable instanceof Collection<?>) { |
| return ((Collection<?>) iterable).contains(o); |
| } |
| return IteratorExtensions.contains(iterable.iterator(), o); |
| } |
| } |