/** * Interleaves two iterables into a single iterable. * <p> * The returned iterable has an iterator that traverses the elements in {@code a} * and {@code b} in alternating order. The source iterators are not polled until * necessary. * <p> * The returned iterable's iterator supports {@code remove()} when the corresponding * input iterator supports it. * * @param <E> the element type * @param a the first iterable, may not be null * @param b the second iterable, may not be null * @return a new iterable, interleaving the provided iterables * @throws NullPointerException if either a or b is null */ public static <E> Iterable<E> zippingIterable(final Iterable<? extends E> a, final Iterable<? extends E> b) { checkNotNull(a); checkNotNull(b); return new FluentIterable<E>() { @Override public Iterator<E> iterator() { return IteratorUtils.zippingIterator(a.iterator(), b.iterator()); } }; }
/** * Returns a unique view of the given iterable. * <p> * The returned iterable's iterator supports {@code remove()} when the * corresponding input iterator supports it. Calling {@code remove()} * will only remove a single element from the underlying iterator. * * @param <E> the element type * @param iterable the iterable to use, may not be null * @return a unique view of the specified iterable * @throws NullPointerException if iterable is null */ public static <E> Iterable<E> uniqueIterable(final Iterable<E> iterable) { checkNotNull(iterable); return new FluentIterable<E>() { @Override public Iterator<E> iterator() { return new UniqueFilterIterator<>(iterable.iterator()); } }; }
/** * Combines the two provided iterables into an ordered iterable using * natural ordering. * <p> * The returned iterable's iterator supports {@code remove()} when the * corresponding input iterator supports it. * * @param <E> the element type * @param a the first iterable, may not be null * @param b the second iterable, may not be null * @return a filtered view on the specified iterable * @throws NullPointerException if either of the provided iterables is null */ public static <E> Iterable<E> collatedIterable(final Iterable<? extends E> a, final Iterable<? extends E> b) { checkNotNull(a, b); return new FluentIterable<E>() { @Override public Iterator<E> iterator() { return IteratorUtils.collatedIterator(null, a.iterator(), b.iterator()); } }; }
/** * Returns a reversed view of the given iterable. * <p> * In case the provided iterable is a {@link List} instance, a * {@link ReverseListIterator} will be used to reverse the traversal * order, otherwise an intermediate {@link List} needs to be created. * <p> * The returned iterable's iterator supports {@code remove()} if the * provided iterable is a {@link List} instance. * * @param <E> the element type * @param iterable the iterable to use, may not be null * @return a reversed view of the specified iterable * @throws NullPointerException if iterable is null * @see ReverseListIterator */ public static <E> Iterable<E> reversedIterable(final Iterable<E> iterable) { checkNotNull(iterable); return new FluentIterable<E>() { @Override public Iterator<E> iterator() { final List<E> list = (iterable instanceof List<?>) ? (List<E>) iterable : IteratorUtils.toList(iterable.iterator()); return new ReverseListIterator<>(list); } }; }
/** * Combines the two provided iterables into an ordered iterable using the * provided comparator. If the comparator is null, natural ordering will be * used. * <p> * The returned iterable's iterator supports {@code remove()} when the * corresponding input iterator supports it. * * @param <E> the element type * @param comparator the comparator defining an ordering over the elements, * may be null, in which case natural ordering will be used * @param a the first iterable, may not be null * @param b the second iterable, may not be null * @return a filtered view on the specified iterable * @throws NullPointerException if either of the provided iterables is null */ public static <E> Iterable<E> collatedIterable(final Comparator<? super E> comparator, final Iterable<? extends E> a, final Iterable<? extends E> b) { checkNotNull(a, b); return new FluentIterable<E>() { @Override public Iterator<E> iterator() { return IteratorUtils.collatedIterator(comparator, a.iterator(), b.iterator()); } }; }
checkNotNull(first); checkNotNull(others); return new FluentIterable<E>() { @Override
/** * Fail-fast check for null arguments. * * @param iterables the iterables to check * @throws NullPointerException if the argument or any of its contents is null */ static void checkNotNull(final Iterable<?>... iterables) { if (iterables == null) { throw new NullPointerException("Iterables must not be null."); } for (final Iterable<?> iterable : iterables) { checkNotNull(iterable); } }
checkNotNull(iterable); return new FluentIterable<E>() { @Override
checkNotNull(iterables); return new FluentIterable<E>() { @Override
/** * Returns a view of the given iterable that skips the first N elements. * <p> * The returned iterable's iterator supports {@code remove()} when the corresponding * input iterator supports it. * * @param <E> the element type * @param iterable the iterable to use, may not be null * @param elementsToSkip the number of elements to skip from the start, must not be negative * @return a view of the specified iterable, skipping the first N elements * @throws IllegalArgumentException if elementsToSkip is negative * @throws NullPointerException if iterable is null */ public static <E> Iterable<E> skippingIterable(final Iterable<E> iterable, final long elementsToSkip) { checkNotNull(iterable); if (elementsToSkip < 0) { throw new IllegalArgumentException("ElementsToSkip parameter must not be negative."); } return new FluentIterable<E>() { @Override public Iterator<E> iterator() { return IteratorUtils.skippingIterator(iterable.iterator(), elementsToSkip); } }; }
/** * Returns a view of the given iterable that only contains elements matching * the provided predicate. * <p> * The returned iterable's iterator supports {@code remove()} when the * corresponding input iterator supports it. * * @param <E> the element type * @param iterable the iterable to filter, may not be null * @param predicate the predicate used to filter elements, may not be null * @return a filtered view on the specified iterable * @throws NullPointerException if either iterable or predicate is null */ public static <E> Iterable<E> filteredIterable(final Iterable<E> iterable, final Predicate<? super E> predicate) { checkNotNull(iterable); if (predicate == null) { throw new NullPointerException("Predicate must not be null."); } return new FluentIterable<E>() { @Override public Iterator<E> iterator() { return IteratorUtils.filteredIterator(emptyIteratorIfNull(iterable), predicate); } }; }
/** * Returns a view of the given iterable that contains at most the given number * of elements. * <p> * The returned iterable's iterator supports {@code remove()} when the corresponding * input iterator supports it. * * @param <E> the element type * @param iterable the iterable to limit, may not be null * @param maxSize the maximum number of elements, must not be negative * @return a bounded view on the specified iterable * @throws IllegalArgumentException if maxSize is negative * @throws NullPointerException if iterable is null */ public static <E> Iterable<E> boundedIterable(final Iterable<E> iterable, final long maxSize) { checkNotNull(iterable); if (maxSize < 0) { throw new IllegalArgumentException("MaxSize parameter must not be negative."); } return new FluentIterable<E>() { @Override public Iterator<E> iterator() { return IteratorUtils.boundedIterator(iterable.iterator(), maxSize); } }; }
/** * Returns a transformed view of the given iterable where all of its elements * have been transformed by the provided transformer. * <p> * The returned iterable's iterator supports {@code remove()} when the corresponding * input iterator supports it. * * @param <I> the input element type * @param <O> the output element type * @param iterable the iterable to transform, may not be null * @param transformer the transformer, must not be null * @return a transformed view of the specified iterable * @throws NullPointerException if either iterable or transformer is null */ public static <I, O> Iterable<O> transformedIterable(final Iterable<I> iterable, final Transformer<? super I, ? extends O> transformer) { checkNotNull(iterable); if (transformer == null) { throw new NullPointerException("Transformer must not be null."); } return new FluentIterable<O>() { @Override public Iterator<O> iterator() { return IteratorUtils.transformedIterator(iterable.iterator(), transformer); } }; }
/** * Returns an unmodifiable view of the given iterable. * <p> * The returned iterable's iterator does not support {@code remove()}. * * @param <E> the element type * @param iterable the iterable to use, may not be null * @return an unmodifiable view of the specified iterable * @throws NullPointerException if iterable is null */ public static <E> Iterable<E> unmodifiableIterable(final Iterable<E> iterable) { checkNotNull(iterable); if (iterable instanceof UnmodifiableIterable<?>) { return iterable; } return new UnmodifiableIterable<>(iterable); }
/** * Construct a new FluentIterable from the provided iterable. If the * iterable is already an instance of FluentIterable, the instance * will be returned instead. * <p> * The returned iterable's iterator supports {@code remove()} when the * corresponding input iterator supports it. * * @param <T> the element type * @param iterable the iterable to wrap into a FluentIterable, may not be null * @return a new FluentIterable wrapping the provided iterable * @throws NullPointerException if iterable is null */ public static <T> FluentIterable<T> of(final Iterable<T> iterable) { IterableUtils.checkNotNull(iterable); if (iterable instanceof FluentIterable<?>) { return (FluentIterable<T>) iterable; } return new FluentIterable<>(iterable); }