diff options
Diffstat (limited to 'guava/src/com/google/common/collect/Iterators.java')
-rw-r--r-- | guava/src/com/google/common/collect/Iterators.java | 182 |
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; - } } |