aboutsummaryrefslogtreecommitdiffstats
path: root/guava/src/com/google/common/collect/Iterators.java
diff options
context:
space:
mode:
Diffstat (limited to 'guava/src/com/google/common/collect/Iterators.java')
-rw-r--r--guava/src/com/google/common/collect/Iterators.java182
1 files changed, 57 insertions, 125 deletions
diff --git a/guava/src/com/google/common/collect/Iterators.java b/guava/src/com/google/common/collect/Iterators.java
index 39e13c3..847d1dd 100644
--- a/guava/src/com/google/common/collect/Iterators.java
+++ b/guava/src/com/google/common/collect/Iterators.java
@@ -24,7 +24,6 @@ import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Function;
-import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
@@ -38,7 +37,6 @@ import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
-import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.PriorityQueue;
import java.util.Queue;
@@ -54,10 +52,6 @@ import javax.annotation.Nullable;
* produced in this class are <i>lazy</i>, which means that they only advance
* the backing iteration when absolutely necessary.
*
- * <p>See the Guava User Guide section on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Iterables">
- * {@code Iterators}</a>.
- *
* @author Kevin Bourrillion
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
@@ -66,8 +60,8 @@ import javax.annotation.Nullable;
public final class Iterators {
private Iterators() {}
- static final UnmodifiableListIterator<Object> EMPTY_LIST_ITERATOR
- = new UnmodifiableListIterator<Object>() {
+ static final UnmodifiableIterator<Object> EMPTY_ITERATOR
+ = new UnmodifiableIterator<Object>() {
@Override
public boolean hasNext() {
return false;
@@ -76,22 +70,6 @@ public final class Iterators {
public Object next() {
throw new NoSuchElementException();
}
- @Override
- public boolean hasPrevious() {
- return false;
- }
- @Override
- public Object previous() {
- throw new NoSuchElementException();
- }
- @Override
- public int nextIndex() {
- return 0;
- }
- @Override
- public int previousIndex() {
- return -1;
- }
};
/**
@@ -100,20 +78,10 @@ public final class Iterators {
* <p>The {@link Iterable} equivalent of this method is {@link
* ImmutableSet#of()}.
*/
- public static <T> UnmodifiableIterator<T> emptyIterator() {
- return emptyListIterator();
- }
-
- /**
- * Returns the empty iterator.
- *
- * <p>The {@link Iterable} equivalent of this method is {@link
- * ImmutableSet#of()}.
- */
// Casting to any type is safe since there are no actual elements.
@SuppressWarnings("unchecked")
- static <T> UnmodifiableListIterator<T> emptyListIterator() {
- return (UnmodifiableListIterator<T>) EMPTY_LIST_ITERATOR;
+ public static <T> UnmodifiableIterator<T> emptyIterator() {
+ return (UnmodifiableIterator<T>) EMPTY_ITERATOR;
}
private static final Iterator<Object> EMPTY_MODIFIABLE_ITERATOR =
@@ -307,11 +275,15 @@ public final class Iterators {
* {@code hasNext()} method will return {@code false}.
*/
public static String toString(Iterator<?> iterator) {
- return Joiner.on(", ")
- .useForNull("null")
- .appendTo(new StringBuilder().append('['), iterator)
- .append(']')
- .toString();
+ if (!iterator.hasNext()) {
+ return "[]";
+ }
+ StringBuilder builder = new StringBuilder();
+ builder.append('[').append(iterator.next());
+ while (iterator.hasNext()) {
+ builder.append(", ").append(iterator.next());
+ }
+ return builder.append(']').toString();
}
/**
@@ -347,8 +319,8 @@ public final class Iterators {
* @throws IllegalArgumentException if the iterator contains multiple
* elements. The state of the iterator is unspecified.
*/
- @Nullable
- public static <T> T getOnlyElement(Iterator<? extends T> iterator, @Nullable T defaultValue) {
+ public static <T> T getOnlyElement(
+ Iterator<T> iterator, @Nullable T defaultValue) {
return iterator.hasNext() ? getOnlyElement(iterator) : defaultValue;
}
@@ -459,8 +431,8 @@ public final class Iterators {
/**
* Returns an iterator that cycles indefinitely over the provided elements.
*
- * <p>The returned iterator supports {@code remove()}. After {@code remove()}
- * is called, subsequent cycles omit the removed
+ * <p>The returned iterator supports {@code remove()} if the provided iterator
+ * does. After {@code remove()} is called, subsequent cycles omit the removed
* element, but {@code elements} does not change. The iterator's
* {@code hasNext()} method returns {@code true} until all of the original
* elements have been removed.
@@ -480,11 +452,6 @@ public final class Iterators {
*
* <p>The returned iterator supports {@code remove()} when the corresponding
* input iterator supports it.
- *
- * <p><b>Note:</b> the current implementation is not suitable for nested
- * concatenated iterators, i.e. the following should be avoided when in a loop:
- * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the
- * resulting iterator has a cubic complexity to the depth of the nesting.
*/
@SuppressWarnings("unchecked")
public static <T> Iterator<T> concat(Iterator<? extends T> a,
@@ -502,11 +469,6 @@ public final class Iterators {
*
* <p>The returned iterator supports {@code remove()} when the corresponding
* input iterator supports it.
- *
- * <p><b>Note:</b> the current implementation is not suitable for nested
- * concatenated iterators, i.e. the following should be avoided when in a loop:
- * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the
- * resulting iterator has a cubic complexity to the depth of the nesting.
*/
@SuppressWarnings("unchecked")
public static <T> Iterator<T> concat(Iterator<? extends T> a,
@@ -525,11 +487,6 @@ public final class Iterators {
*
* <p>The returned iterator supports {@code remove()} when the corresponding
* input iterator supports it.
- *
- * <p><b>Note:</b> the current implementation is not suitable for nested
- * concatenated iterators, i.e. the following should be avoided when in a loop:
- * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the
- * resulting iterator has a cubic complexity to the depth of the nesting.
*/
@SuppressWarnings("unchecked")
public static <T> Iterator<T> concat(Iterator<? extends T> a,
@@ -550,11 +507,6 @@ public final class Iterators {
* <p>The returned iterator supports {@code remove()} when the corresponding
* input iterator supports it.
*
- * <p><b>Note:</b> the current implementation is not suitable for nested
- * concatenated iterators, i.e. the following should be avoided when in a loop:
- * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the
- * resulting iterator has a cubic complexity to the depth of the nesting.
- *
* @throws NullPointerException if any of the provided iterators is null
*/
public static <T> Iterator<T> concat(Iterator<? extends T>... inputs) {
@@ -569,11 +521,6 @@ public final class Iterators {
* <p>The returned iterator supports {@code remove()} when the corresponding
* input iterator supports it. The methods of the returned iterator may throw
* {@code NullPointerException} if any of the input iterators is null.
- *
- * <p><b>Note:</b> the current implementation is not suitable for nested
- * concatenated iterators, i.e. the following should be avoided when in a loop:
- * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the
- * resulting iterator has a cubic complexity to the depth of the nesting.
*/
public static <T> Iterator<T> concat(
final Iterator<? extends Iterator<? extends T>> inputs) {
@@ -764,8 +711,8 @@ public final class Iterators {
* predicate; use this method only when such an element is known to exist. If
* no such element is found, the iterator will be left exhausted: its {@code
* hasNext()} method will return {@code false}. If it is possible that
- * <i>no</i> element will match, use {@link #tryFind} or {@link
- * #find(Iterator, Predicate, Object)} instead.
+ * <i>no</i> element will match, use {@link #tryFind)} or {@link
+ * #find(Iterator, Predicate, T)} instead.
*
* @throws NoSuchElementException if no element in {@code iterator} matches
* the given predicate
@@ -785,10 +732,9 @@ public final class Iterators {
*
* @since 7.0
*/
- @Nullable
- public static <T> T find(Iterator<? extends T> iterator, Predicate<? super T> predicate,
+ public static <T> T find(Iterator<T> iterator, Predicate<? super T> predicate,
@Nullable T defaultValue) {
- UnmodifiableIterator<? extends T> filteredIterator = filter(iterator, predicate);
+ UnmodifiableIterator<T> filteredIterator = filter(iterator, predicate);
return filteredIterator.hasNext() ? filteredIterator.next() : defaultValue;
}
@@ -853,12 +799,22 @@ public final class Iterators {
*/
public static <F, T> Iterator<T> transform(final Iterator<F> fromIterator,
final Function<? super F, ? extends T> function) {
+ checkNotNull(fromIterator);
checkNotNull(function);
- return new TransformedIterator<F, T>(fromIterator) {
+ return new Iterator<T>() {
+ @Override
+ public boolean hasNext() {
+ return fromIterator.hasNext();
+ }
@Override
- T transform(F from) {
+ public T next() {
+ F from = fromIterator.next();
return function.apply(from);
}
+ @Override
+ public void remove() {
+ fromIterator.remove();
+ }
};
}
@@ -910,8 +866,8 @@ public final class Iterators {
* @throws IndexOutOfBoundsException if {@code position} is negative
* @since 4.0
*/
- @Nullable
- public static <T> T get(Iterator<? extends T> iterator, int position, @Nullable T defaultValue) {
+ public static <T> T get(Iterator<T> iterator, int position,
+ @Nullable T defaultValue) {
checkNonnegative(position);
try {
@@ -930,8 +886,7 @@ public final class Iterators {
* @return the next element of {@code iterator} or the default value
* @since 7.0
*/
- @Nullable
- public static <T> T getNext(Iterator<? extends T> iterator, @Nullable T defaultValue) {
+ public static <T> T getNext(Iterator<T> iterator, @Nullable T defaultValue) {
return iterator.hasNext() ? iterator.next() : defaultValue;
}
@@ -958,24 +913,24 @@ public final class Iterators {
* @return the last element of {@code iterator}
* @since 3.0
*/
- @Nullable
- public static <T> T getLast(Iterator<? extends T> iterator, @Nullable T defaultValue) {
+ public static <T> T getLast(Iterator<T> iterator, @Nullable T defaultValue) {
return iterator.hasNext() ? getLast(iterator) : defaultValue;
}
/**
- * Calls {@code next()} on {@code iterator}, either {@code numberToAdvance} times
+ * Calls {@code next()} on {@code iterator}, either {@code numberToSkip} times
* or until {@code hasNext()} returns {@code false}, whichever comes first.
*
- * @return the number of elements the iterator was advanced
- * @since 13.0 (since 3.0 as {@code Iterators.skip})
+ * @return the number of elements skipped
+ * @since 3.0
*/
- public static int advance(Iterator<?> iterator, int numberToAdvance) {
+ @Beta
+ public static <T> int skip(Iterator<T> iterator, int numberToSkip) {
checkNotNull(iterator);
- checkArgument(numberToAdvance >= 0, "number to advance cannot be negative");
+ checkArgument(numberToSkip >= 0, "number to skip cannot be negative");
int i;
- for (i = 0; i < numberToAdvance && iterator.hasNext(); i++) {
+ for (i = 0; i < numberToSkip && iterator.hasNext(); i++) {
iterator.next();
}
return i;
@@ -1051,21 +1006,6 @@ public final class Iterators {
};
}
- /**
- * Deletes and returns the next value from the iterator, or returns
- * {@code defaultValue} if there is no such value.
- */
- @Nullable
- static <T> T pollNext(Iterator<T> iterator) {
- if (iterator.hasNext()) {
- T result = iterator.next();
- iterator.remove();
- return result;
- } else {
- return null;
- }
- }
-
// Methods only in Iterators, not in Iterables
/**
@@ -1103,14 +1043,21 @@ public final class Iterators {
}
/**
- * Returns a list iterator containing the elements in the specified range of
- * {@code array} in order, starting at the specified index.
+ * Returns an iterator containing the elements in the specified range of
+ * {@code array} in order. The returned iterator is a view of the array;
+ * subsequent changes to the array will be reflected in the iterator.
*
* <p>The {@code Iterable} equivalent of this method is {@code
- * Arrays.asList(array).subList(offset, offset + length).listIterator(index)}.
+ * Arrays.asList(array).subList(offset, offset + length)}.
+ *
+ * @param array array to read elements out of
+ * @param offset index of first array element to retrieve
+ * @param length number of elements in iteration
+ * @throws IndexOutOfBoundsException if {@code offset} is negative, {@code
+ * length} is negative, or {@code offset + length > array.length}
*/
- static <T> UnmodifiableListIterator<T> forArray(
- final T[] array, final int offset, int length, int index) {
+ static <T> UnmodifiableIterator<T> forArray(
+ final T[] array, final int offset, int length) {
checkArgument(length >= 0);
int end = offset + length;
@@ -1122,7 +1069,7 @@ public final class Iterators {
* because the returned Iterator is a ListIterator that may be moved back
* past the beginning of the iteration.
*/
- return new AbstractIndexedListIterator<T>(length, index) {
+ return new AbstractIndexedListIterator<T>(length) {
@Override protected T get(int index) {
return array[offset + index];
}
@@ -1379,19 +1326,4 @@ public final class Iterators {
return next;
}
}
-
- /**
- * Precondition tester for {@code Iterator.remove()} that throws an exception with a consistent
- * error message.
- */
- static void checkRemove(boolean canRemove) {
- checkState(canRemove, "no calls to next() since the last call to remove()");
- }
-
- /**
- * Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557
- */
- static <T> ListIterator<T> cast(Iterator<T> iterator) {
- return (ListIterator<T>) iterator;
- }
}