com.google.inject.internal.Iterables Maven / Gradle / Ivy
/*
* 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;
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 getOnlyElement(Iterable 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.
*
* The returned iterable's iterator supports {@code remove()} when the
* corresponding input iterator supports it.
*/
@SuppressWarnings("unchecked")
public static Iterable 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.
*
* 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 Iterable 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 function = new Function {
* public B apply(A from) {
* return from.iterator();
* }
* }
*
* TODO: there may be a better way to do this.
*/
Function, Iterator extends T>> function
= new Function, Iterator extends T>>() {
public Iterator extends T> apply(Iterable extends T> from) {
return from.iterator();
}
};
final Iterable> iterators
= transform(inputs, function);
return new IterableWithToString() {
public Iterator iterator() {
return Iterators.concat(iterators.iterator());
}
};
}
/**
* Returns an iterable that applies {@code function} to each element of {@code
* fromIterable}.
*
* 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 Iterable transform(final Iterable fromIterable,
final Function super F, ? extends T> function) {
Preconditions.checkNotNull(fromIterable);
Preconditions.checkNotNull(function);
return new IterableWithToString() {
public Iterator iterator() {
return Iterators.transform(fromIterable.iterator(), function);
}
};
}
// Methods only in Iterables, not in Iterators
abstract static class IterableWithToString implements Iterable {
@Override public String toString() {
return Iterables.toString(this);
}
}
}