blob: ab2835d5b0ec37a99092f1f3f5d7ecdf672b0ef0 [file] [log] [blame]
/*
* 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);
}
}
}