/* * Copyright (C) 2007 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.inject.internal.util; import java.util.Arrays; import java.util.Iterator; import java.util.NoSuchElementException; /** * This class contains static utility methods that operate on or return objects * of type {@code Iterable}. Also see the parallel implementations in {@link * Iterators}. * * @author Kevin Bourrillion * @author Scott Bonneau */ public final class Iterables { private Iterables() {} /** * Returns a string representation of {@code iterable}, with the format * {@code [e1, e2, ..., en]}. */ public static String toString(Iterable<?> iterable) { return Iterators.toString(iterable.iterator()); } /** * Returns the single element contained in {@code iterable}. * * @throws NoSuchElementException if the iterable is empty * @throws IllegalArgumentException if the iterable contains multiple * elements */ public static <T> T getOnlyElement(Iterable<T> iterable) { return Iterators.getOnlyElement(iterable.iterator()); } /** * Combines 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 source iterators are not polled until necessary. * * <p>The returned iterable's iterator supports {@code remove()} when the * corresponding input iterator supports it. */ @SuppressWarnings("unchecked") public static <T> Iterable<T> concat( Iterable<? extends T> a, Iterable<? extends T> b) { Preconditions.checkNotNull(a); Preconditions.checkNotNull(b); return concat(Arrays.asList(a, b)); } /** * 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. */ public static <T> Iterable<T> concat( Iterable<? extends Iterable<? extends T>> inputs) { /* * Hint: if you let A represent Iterable<? extends T> and B represent * Iterator<? extends T>, then this Function would look simply like: * * Function<A, B> function = new Function<A, B> { * public B apply(A from) { * return from.iterator(); * } * } * * TODO: there may be a better way to do this. */ Function<Iterable<? extends T>, Iterator<? extends T>> function = new Function<Iterable<? extends T>, Iterator<? extends T>>() { public Iterator<? extends T> apply(Iterable<? extends T> from) { return from.iterator(); } }; final Iterable<Iterator<? extends T>> iterators = transform(inputs, function); return new IterableWithToString<T>() { public Iterator<T> iterator() { return Iterators.concat(iterators.iterator()); } }; } /** * Returns an iterable that applies {@code function} to each element of {@code * fromIterable}. * * <p>The returned iterable's iterator supports {@code remove()} if the * provided iterator does. After a successful {@code remove()} call, * {@code fromIterable} no longer contains the corresponding element. */ public static <F, T> Iterable<T> transform(final Iterable<F> fromIterable, final Function<? super F, ? extends T> function) { Preconditions.checkNotNull(fromIterable); Preconditions.checkNotNull(function); return new IterableWithToString<T>() { public Iterator<T> iterator() { return Iterators.transform(fromIterable.iterator(), function); } }; } // Methods only in Iterables, not in Iterators abstract static class IterableWithToString<E> implements Iterable<E> { @Override public String toString() { return Iterables.toString(this); } } }