Java tutorial
/* * Copyright (c) 2005-2011 Clark & Parsia, LLC. <http://www.clarkparsia.com> * * 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.complexible.common.collect; import java.util.Iterator; import java.util.NoSuchElementException; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.collect.AbstractIterator; import com.google.common.collect.PeekingIterator; import com.google.common.collect.UnmodifiableIterator; /** * <p>Utility methods for using Iterators which are not present in the Guava Iterators class. Also includes re-implementations of some methods, filter and transform, found * in Iterators but which are slightly faster than their Guava counterparts because they avoid all safety checks. These can be used when you know there are no nulls in your collections * and the Predicate/Function itself will not be null or ever return a null value.</p> * * @author Michael Grove * @author Pedro Oliveira * @since 2.0 * @version 3.1.1 */ public final class Iterators2 { /** * Private constructor */ private Iterators2() { throw new AssertionError(); } public static <T> PeekingIterator<T> peekingIterator(final Iterator<T> theIterator) { if (theIterator instanceof PeekingIterator) { return (PeekingIterator<T>) theIterator; } else { return new PeekingIteratorAdapter<T>(theIterator); } } /** * Creates an {@link Iterator} that returns the same element a predetermined number of times * * @param <T> the type of the element * @param theElement the element to return * @param theNumberOfTimes the number of times to repeat the element * @return an Iterator that will repeat the given element the specified number of times */ public static <T> Iterator<T> repeat(final T theElement, final long theNumberOfTimes) { return new UnmodifiableIterator<T>() { long count = 0; public boolean hasNext() { return count < theNumberOfTimes; } public T next() { count++; return theElement; } }; } public static <T> Iterator<T> present(final Iterator<Optional<T>> theIter) { return new AbstractIterator<T>() { @Override protected T computeNext() { while (theIter.hasNext()) { Optional<T> aOptional = theIter.next(); if (aOptional.isPresent()) { return aOptional.get(); } } return endOfData(); } }; } /** * Returns the elements of {@code unfiltered} that satisfy a predicate. * @param unfiltered the unfiltered iterator * @param predicate the predicate to use to filter * @return the filtered iterator */ public static <T> UnmodifiableIterator<T> filter(final Iterator<T> unfiltered, final Predicate<? super T> predicate) { return new AbstractIterator<T>() { /** * @inheritDoc */ @Override protected T computeNext() { while (unfiltered.hasNext()) { T element = unfiltered.next(); if (predicate.apply(element)) { return element; } } return endOfData(); } }; } /** * Transform the elements of the given Iterator using the function. * @param theIterator the iterator to transform * @param theFunction the function to transform with * @return the transformed iterator */ public static <T, S> Iterator<T> transform(final Iterator<S> theIterator, final Function<? super S, ? extends T> theFunction) { return new UnmodifiableIterator<T>() { /** * @inheritDoc */ public boolean hasNext() { return theIterator.hasNext(); } /** * @inheritDoc */ public T next() { return theFunction.apply(theIterator.next()); } }; } /** * Create an Iterator for the given sub-array * @param theArray the array * @param <T> the type of elements in the array * @return an Iterator over the array */ public static <T> PeekingIterator<T> forArray(final T... theArray) { return new ArrayIterator<T>(theArray); } /** * Create an Iterator for the given sub-array * @param theArray the array * @param theStart the starting index for iteration * @param theEnd the ending index for iteration * @param <T> the type of elements in the array * @return an Iterator over the array */ public static <T> PeekingIterator<T> forArray(final T[] theArray, final int theStart, final int theEnd) { return new ArrayIterator<T>(theArray, theStart, theEnd); } private static final PeekingIterator<Object> EMPTY_PEEKING_ITERATOR = new PeekingIterator<Object>() { @Override public Object next() { throw new NoSuchElementException(); } @Override public Object peek() { throw new NoSuchElementException(); } @Override public void remove() { throw new IllegalStateException(); } @Override public boolean hasNext() { return false; } }; @SuppressWarnings("unchecked") public static <T> PeekingIterator<T> emptyPeekingIterator() { return (PeekingIterator<T>) EMPTY_PEEKING_ITERATOR; } private static final class PeekingIteratorAdapter<T> extends AbstractIterator<T> implements PeekingIterator<T> { private final Iterator<T> mIter; private PeekingIteratorAdapter(final Iterator<T> theIter) { mIter = theIter; } @Override protected T computeNext() { if (mIter.hasNext()) { return mIter.next(); } else { return endOfData(); } } } }