/* XXL: The eXtensible and fleXible Library for data processing Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger Head of the Database Research Group Department of Mathematics and Computer Science University of Marburg Germany This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; If not, see <http://www.gnu.org/licenses/>. http://code.google.com/p/xxl/ */ package xxl.core.cursors; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.PrintStream; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Map.Entry; import xxl.core.comparators.ComparableComparator; import xxl.core.comparators.InverseComparator; import xxl.core.cursors.groupers.Minimator; import xxl.core.cursors.mappers.Mapper; import xxl.core.cursors.sources.io.FileInputCursor; import xxl.core.cursors.wrappers.IteratorCursor; import xxl.core.functions.AbstractFunction; import xxl.core.functions.Function; import xxl.core.functions.Identity; import xxl.core.functions.PredicateFunction; import xxl.core.functions.Print; import xxl.core.io.converters.Converter; import xxl.core.predicates.Predicate; import xxl.core.util.ArrayResizer; import xxl.core.util.WrappingRuntimeException; /** * This class contains various <tt>static</tt> methods for manipulating * iterators. For example : * <ul> * <li> * A user defined function can be applied to each element of an * iterator, to a couple of elements of two iterators traversed * synchronously or even to a set of elements of an array of iterators. * </li> * <li> * A condition can be checked for a whole iterator by invoking a given * boolean function or predicate on it. * </li> * <li> * Useful methods are given to determine the first, the last or the * <tt>n</tt>'th element of an iterator, its minima and maxima and to * update or remove all elements of an iterator. * </li> * <li> * Some converters are given, i.e., the caller is able to convert an * iterator to a list, a map, a collection or an array. * </li> * </ul> * * <p><b>Example usage (1):</b> * <code><pre> * Cursor<Integer> cursor = new Enumerator(11); * cursor.open(); * * System.out.println("First element : " + Cursors.first(cursor)); * * cursor.reset(); * System.out.println("Third element : " + Cursors.nth(cursor, 3)); * * cursor.reset(); * System.out.println("Last element : " + Cursors.last(cursor)); * * cursor.reset(); * System.out.println("Length : " + Cursors.count(cursor)); * * cursor.close(); * </pre></code> * These examples demonstrate some useful static methods for navigation in a * cursor.</p> * * <p><b>Example usage (2):</b> * <code><pre> * Map.Entry<?, LinkedList<Integer>> entry = Cursors.maximize( * cursor = new DiscreteRandomNumber(new JavaDiscreteRandomWrapper(100), 50), * new Identity<Integer>() * ); * System.out.println("Maximum value is : " + entry.getKey()); * * System.out.print("Maxima : "); * for (Integer next : entry.getValue()) * System.out.print(next + "; "); * System.out.flush(); * * cursor.close(); * </pre></code> * This example computes the maximum value of 50 randomly distributed integers * of the interval [0, 100) using a mapping. Also an iterator containing all * maxima is printed to the output.</p> * * <p><b>Example usage (3):</b> * <code><pre> * Cursors.forEach( * new Function<Integer, Integer>() { * public Integer invoke(Integer object) { * Integer result = (int)Math.pow(object, 2); * System.out.println("Number : " + object + " ; Number^2 : " + result); * return result; * } * }, * cursor = new Enumerator(11) * ); * cursor.close(); * </pre></code> * This example computes the square value for each element of the given * enumerator with range 0,...,10.</p> * * <p><b>Example usage (4):</b> * <code><pre> * System.out.println( * "Is the number '13' contained in the discrete random numbers' cursor : " + * Cursors.any( * new Predicate<Integer>() { * public boolean invoke(Integer object) { * return object == 13; * } * }, * cursor = new DiscreteRandomNumber(new JavaDiscreteRandomWrapper(1000), 200) * ) * ); * cursor.close(); * </pre></code> * This example checks if a cursor of 200 randomly distributed integers with * maximum value 999 contains the value 13 by evaluating a predictate on its * elements. It returns <code>true</code> if the predicate is <code>true</code> * for only one element of the input cursor.</p> * * @see java.util.Iterator * @see xxl.core.cursors.Cursor * @see xxl.core.functions.Function * @see xxl.core.predicates.Predicate * @see java.util.Collection * @see java.util.List * @see java.util.Map * @see java.util.Map.Entry * @see java.util.Comparator */ public abstract class Cursors { /** * The default constructor has private access in order to ensure * non-instantiability. */ private Cursors() { // private access in order to ensure non-instantiability } /** * Invokes the higher-order function on each set of elements given by the * input iterator array. The set contains one element per iterator and the * function is only invoked while all iterators are not empty. * * @param <E> the type of the elements returned by the given iterator. * @param <R> the type of the elements returned by the given function. * @param function the function to be invoked on each set of elements. * @param iterators the iterators used to get a set of elements by taking * one element per iterator. */ public static <E, R> void forEach(Function<? super E, R> function, Iterator<? extends E>... iterators) { Cursors.consume(new Mapper<E, R>(function, iterators)); } /** * Returns <code>true</code> if the boolean higher-order function returns * {@link java.lang.Boolean#TRUE true} applied on each set of elements of * the given input iterator array. The set contains one element per * iterator and the function is only applied while all iterators are not * empty. * * @param <E> the type of the elements returned by the given iterator. * @param function the function to be invoked on each set of elements. * @param iterators the iterators used to get a set of elements by taking * one element of each iterator. * @return <code>true</code> if the function returns * {@link java.lang.Boolean#TRUE true} for each set of elements of * the given input iterator array, otherwise <code>false</code>. */ public static <E> boolean all(Function<? super E, Boolean> function, Iterator<? extends E>... iterators) { for (Iterator<Boolean> mapper = new Mapper<E, Boolean>(function, iterators); mapper.hasNext();) if (!mapper.next()) return false; return true; } /** * Returns <code>true</code> if the given predicate is <code>true</code> * for each set of elements of the given input iterator array. The set * contains one element per iterator and the predicate is only applied * while all iterators are not empty. * * @param <E> the type of the elements returned by the given iterator. * @param predicate the predicate to be invoked on each set of elements. * @param iterators the iterators used to get a set of elements by taking one * element of each iterator. * @return <code>true</code> if the predicate returns <code>true</code> for * each set of elements of the given input iterator array, * otherwise <code>false</code>. */ public static <E> boolean all(Predicate<? super E> predicate, Iterator<? extends E>... iterators) { for (Iterator<Boolean> mapper = new Mapper<E, Boolean>(new PredicateFunction<E>(predicate), iterators); mapper.hasNext();) if (!mapper.next()) return false; return true; } /** * Returns <code>true</code> if the boolean higher-order function returns * {@link java.lang.Boolean#TRUE true} applied on any set of elements of * the given input iterator array. The set contains one element per * iterator and the function is only applied while all iterators are not * empty. * * @param <E> the type of the elements returned by the given iterator. * @param function the function to be invoked on each set of elements. * @param iterators the iterators used to get a set of elements by taking one * element of each iterator. * @return <code>true</code> if the function returns * {@link java.lang.Boolean#TRUE true} for any set of elements of * the given input iterator array, otherwise <code>false</code>. */ public static <E> boolean any(Function<? super E, Boolean> function, Iterator<? extends E>... iterators) { for (Iterator<Boolean> mapper = new Mapper<E, Boolean>(function, iterators); mapper.hasNext();) if (mapper.next()) return true; return false; } /** * Returns <code>true</code> if the given predicate returns * <code>true</code> for any set of elements of the given input iterator * array. The set contains one element per iterator and the predicate is * only applied while all iterators are not empty. * * @param <E> the type of the elements returned by the given iterator. * @param predicate the predicate to be invoked on each set of elements. * @param iterators the iterators used to get a set of elements by taking * one element of each iterator. * @return <code>true</code> if the predicate returns <code>true</code> for * any set of elements of the given input iterator array, otherwise * <code>false</code>. */ public static <E> boolean any(Predicate<? super E> predicate, Iterator<? extends E>... iterators) { for (Iterator<Boolean> mapper = new Mapper<E, Boolean>(new PredicateFunction<E>(predicate), iterators); mapper.hasNext();) if (mapper.next()) return true; return false; } /** * Returns the last element of the given iterator. * * @param <E> the type of the elements returned by the given iterator. * @param iterator the input iterator. * @return the last element of the given iterator. * @throws java.util.NoSuchElementException if the iterator does not * contain any elements. */ public static <E> E last(Iterator<E> iterator) throws NoSuchElementException { E result; do result = iterator.next(); while (iterator.hasNext()); return result; } /** * Returns the <code>n</code>-th element of the given iterator. * * @param <E> the type of the elements returned by the given iterator. * @param iterator the input iterator. * @param n the index of the element to return. * @return the <code>n</code>-th element of the given iterator. * @throws java.util.NoSuchElementException if the iterator does not * contain <code>n+1</code> elements. */ public static <E> E nth(Iterator<E> iterator, int n) throws NoSuchElementException { if (n < 0) throw new NoSuchElementException("the given index must be greater than or equal to 0"); E result = null; for (int i = 0; i <= n; i++) result = iterator.next(); return result; } /** * Returns the first element of the given iterator. * * @param <E> the type of the elements returned by the given iterator. * @param iterator the input iterator. * @return the first element of the given iterator. * @throws java.util.NoSuchElementException if the iterator does not * contain any elements. */ public static <E> E first(Iterator<E> iterator) throws NoSuchElementException { return nth(iterator, 0); } /** * Counts the elements of a specified iterator. * * @param iterator the input iterator. * @return the number of elements of the given iterator. */ public static int count(Iterator<?> iterator) { int size = 0; while (iterator.hasNext()) { iterator.next(); size++; } return size; } /** * Calls <code>next</code> on the iterator until the method * <code>hasNext</code> returns <code>false</code>. * * @param iterator the input iterator. */ public static void consume(Iterator<?> iterator) { while (iterator.hasNext()) iterator.next(); } /** * Calls <code>next</code> on the iterator until the method * <code>hasNext</code> returns <code>false</code> and prints the elements * of the iterator separated by a line feed to the standard output stream. * * @param iterator the input iterator. */ public static void println(Iterator<?> iterator) { forEach(Print.PRINTLN_INSTANCE, iterator); } /** * Calls <code>next</code> on the iterator until the method * <code>hasNext</code> returns <code>false</code> and prints the elements * of the iterator to the standard output stream. * * @param iterator the input iterator. */ public static void print(Iterator<?> iterator) { forEach(Print.PRINT_INSTANCE, iterator); } /** * Calls <code>next</code> on the iterator until the method * <code>hasNext</code> returns <code>false</code> and prints the elements * of the iterator separated by a line feed to the specified print stream. * * @param <E> the type of the elements returned by the iteration. * @param iterator the input iterator. * @param printStream the print stream the output is delegated to. */ public static <E> void println(Iterator<E> iterator, PrintStream printStream) { forEach(new Print<E>(printStream, true), iterator); } /** * Calls <code>next</code> on the iterator until the method * <code>hasNext</code> returns <code>false</code> and prints the elements * of the iterator to the specified print stream. * * @param <E> the type of the elements returned by the iteration. * @param iterator the input iterator. * @param printStream the print stream the output is delegated to. */ public static <E> void print(Iterator<E> iterator, PrintStream printStream) { forEach(new Print<E>(printStream, false), iterator); } /** * Returns a {@link java.util.Map.Entry Map.Entry} object with the minimal * value as its key and the list of objects with this minimal value in the * same order as provided by the iterator as its value. * * @param <E> the type of the elements returned by the iteration to be * aggregated. * @param <M> the type of the mapped elements generated by the specified * mapping function. * @param iterator the objects to be minimized. * @param getFeature the function obtaining the value for each object used * to compare. * @param comparator the comparator that compares the values obtained by * <code>getFeature</code>. * @return a map entry with the minimal value as its key and the list of * objects with this minimal value in the same order as provided by * the iterator as its value. */ public static <E, M> Entry<M, LinkedList<E>> minimize(Iterator<? extends E> iterator, Function<? super E, ? extends M> getFeature, Comparator<? super M> comparator) { return last(new Minimator<E, M>(iterator, getFeature, comparator)); } /** * Returns a {@link java.util.Map.Entry Map.Entry} object with the maximal * value as its key and the list of objects with this maximal value in the * same order as provided by the iterator as its value. * * @param <E> the type of the elements returned by the iteration to be * aggregated. * @param <M> the type of the mapped elements generated by the specified * mapping function. * @param iterator the objects to be maximized. * @param getFeature the function obtaining the value for each object used * to compare. * @param comparator the comparator that compares the values obtained by * <code>getFeature</code>. * @return a map entry with the maximal value as its key and the list of * objects with this maximal value in the same order as provided by * the iterator as its value. */ public static <E, M> Entry<M, LinkedList<E>> maximize(Iterator<? extends E> iterator, Function<? super E, ? extends M> getFeature, Comparator<? super M> comparator) { return last(new Minimator<E, M>(iterator, getFeature, new InverseComparator<M>(comparator))); } /** * Returns the list of objects having the minimal value in the same order * as provided by the iterator as its value. * * @param <E> the type of the elements returned by the iteration to be * aggregated. * @param <M> the type of the mapped elements generated by the specified * mapping function. * @param iterator the objects to be minimized. * @param getFeature the function obtaining the value for each object used * to compare. * @param comparator the comparator that compares the values obtained by * <code>getFeature</code>. * @return a linked list of objects having the minimal value in the same * order as provided by the iterator. */ public static <E, M> LinkedList<E> minima(Iterator<? extends E> iterator, Function<? super E, ? extends M> getFeature, Comparator<? super M> comparator) { return minimize(iterator, getFeature, comparator).getValue(); } /** * Returns the list of objects having the maximal value in the same order * as provided by the iterator as its value. * * @param <E> the type of the elements returned by the iteration to be * aggregated. * @param <M> the type of the mapped elements generated by the specified * mapping function. * @param iterator the objects to be maximized. * @param getFeature the function obtaining the value for each object used * to compare. * @param comparator the comparator that compares the values obtained by * <code>getFeature</code>. * @return a linked list of objects having the maximal value in the same * order as provided by the iterator. */ public static <E, M> LinkedList<E> maxima(Iterator<? extends E> iterator, Function<? super E, ? extends M> getFeature, Comparator<? super M> comparator) { return maximize(iterator, getFeature, comparator).getValue(); } /** * Returns a {@link java.util.Map.Entry Map.Entry} object with the minimal * value as its key and the list of objects with this minimal value in the * same order as provided by the iterator as its value. For being able to * use a default * {@link xxl.core.comparators.ComparableComparator comparator} all * elements of the iteration must implement the interface * {@link java.lang.Comparable}. * * @param <E> the type of the elements returned by the iteration to be * aggregated. * @param <M> the type of the mapped elements generated by the specified * mapping function. * @param iterator the objects to be minimized. * @param getFeature the function obtaining the value for each object used * to compare. * @return a map entry with the minimal value as its key and the list of * objects with this minimal value in the same order as provided by * the iterator as its value. */ public static <E, M extends Comparable<M>> Entry<M, LinkedList<E>> minimize(Iterator<? extends E> iterator, Function<? super E, ? extends M> getFeature) { return last(new Minimator<E, M>(iterator, getFeature, new ComparableComparator<M>())); } /** * Returns a {@link java.util.Map.Entry Map.Entry} object with the maximal * value as its key and the list of objects with this maximal value in the * same order as provided by the iterator as its value. For being able to * use a default * {@link xxl.core.comparators.ComparableComparator comparator} all * elements of the iteration must implement the interface * {@link java.lang.Comparable}. * * @param <E> the type of the elements returned by the iteration to be * aggregated. * @param <M> the type of the mapped elements generated by the specified * mapping function. * @param iterator the objects to be maximized. * @param getFeature the function obtaining the value for each object used * to compare. * @return a map entry with the maximal value as its key and the list of * objects with this maximal value in the same order as provided by * the iterator as its value. */ public static <E, M extends Comparable<M>> Entry<M, LinkedList<E>> maximize(Iterator<? extends E> iterator, Function<? super E, ? extends M> getFeature) { return last(new Minimator<E, M>(iterator, getFeature, new InverseComparator<M>(new ComparableComparator<M>()))); } /** * Returns the list of objects having the minimal value in the same order * as provided by the iterator as its value. For being able to use a * default {@link xxl.core.comparators.ComparableComparator comparator} all * elements of the iteration must implement the interface * {@link java.lang.Comparable}. * * @param <E> the type of the elements returned by the iteration to be * aggregated. * @param <M> the type of the mapped elements generated by the specified * mapping function. * @param iterator the objects to be minimized. * @param getFeature the function obtaining the value for each object used * to compare. * @return a linked list of objects having the minimal value in the same * order as provided by the iterator. */ public static <E, M extends Comparable<M>> LinkedList<E> minima(Iterator<? extends E> iterator, Function<? super E, ? extends M> getFeature) { return minimize(iterator, getFeature).getValue(); } /** * Returns the list of objects having the maximal value in the same order * as provided by the iterator as its value. For being able to use a * default {@link xxl.core.comparators.ComparableComparator comparator} all * elements of the iteration must implement the interface * {@link java.lang.Comparable}. * * @param <E> the type of the elements returned by the iteration to be * aggregated. * @param <M> the type of the mapped elements generated by the specified * mapping function. * @param iterator the objects to be maximized. * @param getFeature the function obtaining the value for each object used * to compare. * @return a linked list of objects having the maximal value in the same * order as provided by the iterator. */ public static <E, M extends Comparable<M>> LinkedList<E> maxima(Iterator<? extends E> iterator, Function<? super E, ? extends M> getFeature) { return maximize(iterator, getFeature).getValue(); } /** * Returns a {@link java.util.Map.Entry Map.Entry} object with the minimal * value as its key and the list of objects with this minimal value in the * same order as provided by the iterator as its value. * * @param <E> the type of the elements returned by the iteration to be * aggregated. * @param iterator the objects to be minimized. * @param comparator the comparator that compares the objects. * @return a map entry with the minimal value as its key and the list of * objects with this minimal value in the same order as provided by * the iterator as its value. */ public static <E> Entry<E, LinkedList<E>> minimize(Iterator<? extends E> iterator, Comparator<? super E> comparator) { return last(new Minimator<E, E>(iterator, new Identity<E>(), comparator)); } /** * Returns a {@link java.util.Map.Entry Map.Entry} object with the maximal * value as its key and the list of objects with this maximal value in the * same order as provided by the iterator as its value. * * @param <E> the type of the elements returned by the iteration to be * aggregated. * @param iterator the objects to be maximized. * @param comparator the comparator that compares the objects. * @return a map entry with the maximal value as its key and the list of * objects with this maximal value in the same order as provided by * the iterator as its value. */ public static <E> Entry<E, LinkedList<E>> maximize(Iterator<? extends E> iterator, Comparator<? super E> comparator) { return last(new Minimator<E, E>(iterator, new Identity<E>(), new InverseComparator<E>(comparator))); } /** * Returns the list of objects having the minimal value in the same order * as provided by the iterator as its value. * * @param <E> the type of the elements returned by the iteration to be * aggregated. * @param iterator the objects to be minimized. * @param comparator the comparator that compares the objects. * @return a linked list of objects having the minimal value in the same * order as provided by the iterator. */ public static <E> LinkedList<E> minima(Iterator<? extends E> iterator, Comparator<? super E> comparator) { return minimize(iterator, comparator).getValue(); } /** * Returns the list of objects having the maximal value in the same order * as provided by the iterator as its value. * * @param <E> the type of the elements returned by the iteration to be * aggregated. * @param iterator the objects to be maximized. * @param comparator the comparator that compares the objects. * @return a linked list of objects having the maximal value in the same * order as provided by the iterator. */ public static <E> LinkedList<E> maxima(Iterator<? extends E> iterator, Comparator<? super E> comparator) { return maximize(iterator, comparator).getValue(); } /** * Returns a {@link java.util.Map.Entry Map.Entry} object with the minimal * value as its key and the list of objects with this minimal value in the * same order as provided by the iterator as its value. For being able to * use a default * {@link xxl.core.comparators.ComparableComparator comparator} all * elements of the iteration must implement the interface * {@link java.lang.Comparable}. * * @param <E> the type of the elements returned by the iteration to be * aggregated. * @param iterator the objects to be minimized. * @return a map entry with the minimal value as its key and the list of * objects with this minimal value in the same order as provided by * the iterator as its value. */ public static <E extends Comparable<E>> Entry<E, LinkedList<E>> minimize(Iterator<? extends E> iterator) { return last(new Minimator<E, E>(iterator, new Identity<E>(), new ComparableComparator<E>())); } /** * Returns a {@link java.util.Map.Entry Map.Entry} object with the maximal * value as its key and the list of objects with this maximal value in the * same order as provided by the iterator as its value. For being able to * use a default * {@link xxl.core.comparators.ComparableComparator comparator} all * elements of the iteration must implement the interface * {@link java.lang.Comparable}. * * @param <E> the type of the elements returned by the iteration to be * aggregated. * @param iterator the objects to be maximized. * @return a map entry with the maximal value as its key and the list of * objects with this maximal value in the same order as provided by * the iterator as its value. */ public static <E extends Comparable<E>> Entry<E, LinkedList<E>> maximize(Iterator<? extends E> iterator) { return last(new Minimator<E, E>(iterator, new Identity<E>(), new InverseComparator<E>(new ComparableComparator<E>()))); } /** * Returns the list of objects having the minimal value in the same order * as provided by the iterator as its value. For being able to use a * default {@link xxl.core.comparators.ComparableComparator comparator} all * elements of the iteration must implement the interface * {@link java.lang.Comparable}. * * @param <E> the type of the elements returned by the iteration to be * aggregated. * @param iterator the objects to be minimized. * @return a linked list of objects having the minimal value in the same * order as provided by the iterator. */ public static <E extends Comparable<E>> LinkedList<E> minima(Iterator<? extends E> iterator) { return minimize(iterator).getValue(); } /** * Returns the list of objects having the maximal value in the same order * as provided by the iterator as its value. For being able to use a * default {@link xxl.core.comparators.ComparableComparator comparator} all * elements of the iteration must implement the interface * {@link java.lang.Comparable}. * * @param <E> the type of the elements returned by the iteration to be * aggregated. * @param iterator the objects to be maximized. * @return a linked list of objects having the maximal value in the same * order as provided by the iterator. */ public static <E extends Comparable<E>> LinkedList<E> maxima(Iterator<? extends E> iterator) { return maximize(iterator).getValue(); } /** * Removes all elements of the given iterator. * * @param iterator the input iterator. */ public static void removeAll(Iterator<?> iterator) { while (iterator.hasNext()) { iterator.next(); iterator.remove(); } } /** * Removes the elements of the given iterator for that the specified * predicate returns <code>true</code>. * * @param <E> the type of the elements returned by the given iterator. * @param iterator the input iterator. * @param predicate a predicate that decides whether an element is removed * or not. */ public static <E> void removeAll(Iterator<E> iterator, Predicate<? super E> predicate) { while (iterator.hasNext()) if (predicate.invoke(iterator.next())) iterator.remove(); } /** * Removes the first element of the given iterator for that the specified * predicate returns <code>true</code>. * * @param <E> the type of the elements returned by the given iterator. * @param iterator the input iterator. * @param predicate a predicate that decides whether an element is removed * or not. * @return true if and only if an element was removed. */ public static <E> boolean removeFirst(Iterator<E> iterator, Predicate<? super E> predicate) { while (iterator.hasNext()) if (predicate.invoke(iterator.next())) { iterator.remove(); return true; } return false; } /** * Updates all elements of a cursor. * * @param <E> the type of the elements returned by the given cursor. * @param cursor the input cursor. * @param objects an iterator with objects to be used for the * <code>update</code> operation. */ public static <E> void updateAll(Cursor<E> cursor, Iterator<? extends E> objects) { while (cursor.hasNext() && objects.hasNext()) { cursor.next(); cursor.update(objects.next()); } } /** * Updates all elements of a cursor with the result of a given, unary * function. * * @param <E> the type of the elements returned by the given iterator. * @param cursor the input cursor. * @param function the unary function used to compute the object for the * <code>update</code> operation. */ public static <E> void updateAll(Cursor<E> cursor, Function<E, ? extends E> function) { while (cursor.hasNext()) cursor.update(function.invoke(cursor.next())); } /** * Adds the elements of the given iteration to a specified * {@link java.util.Collection collection}. * * @param <E> the type of the elements returned by the given iterator. * @param iterator the input iterator. * @param collection the collection into which the elements of the given * iteration are to be stored. * @return the specified collection containing the elements of the * iteration. */ public static <E> Collection<E> toCollection(Iterator<? extends E> iterator, Collection<E> collection) { while (iterator.hasNext()) collection.add(iterator.next()); return collection; } /** * Adds the elements of the given iteration to a specified * {@link java.util.List list}. * * @param <E> the type of the elements returned by the given iterator. * @param iterator the input iterator. * @param list the list into which the elements of the given iteration are * to be stored. * @return the specified list containing the elements of the iteration. */ public static <E> List<E> toList(Iterator<? extends E> iterator, List<E> list) { return (List<E>)toCollection(iterator, list); } /** * Adds the elements of the given iteration to a * {@link java.util.LinkedList linked list} and returns it. * * @param <E> the type of the elements returned by the given iterator. * @param iterator the input iterator. * @return the linked list containing the elements of the iteration. */ public static <E> List<E> toList(Iterator<E> iterator) { return toList(iterator, new LinkedList<E>()); } /** * Converts an iterator to an object array whose length is equal to the * number of the iterator's elements. * * @param iterator the input iterator. * @return an object array containing the iterator's elements. */ public static Object[] toArray(Iterator<? extends Object> iterator) { return toFittingArray(iterator, new Object[0]); } /** * Converts an iterator to an object array whose length is determined by * the largest index. Stops as soon as one iterator is exhausted. * * @param iterator the input iterator. * @param indices each index determines where to store the corresponding * iterator element. * @return an object array of the iterator's elements following the order * defined by the iterator <tt>indices</tt>. */ public static Object[] toArray(Iterator<?> iterator, Iterator<Integer> indices) { return toFittingArray(iterator, new Object[0], indices); } /** * Converts an iterator to an object array using the given one. The order * is defined by the given indices iterator. Stops as soon as one iterator * is exhausted. Throws an * {@link java.lang.ArrayIndexOutOfBoundsException ArrayIndexOutOfBoundsException} * if the given array is not long enough. * * @param <E> the type of the elements returned by the given iterator. * @param iterator the input iterator. * @param array the array into which the elements of the given iteration * are to be stored. * @param indices each index determines where to store the corresponding * iterator element. * @return the object array containing the iterator's elements following * the order defined by the iterator <tt>indices</tt>. * @throws java.lang.ArrayIndexOutOfBoundsException if the given array is * not long enough. */ public static <E> E[] toArray(Iterator<? extends E> iterator, E[] array, Iterator<Integer> indices) { while (iterator.hasNext() && indices.hasNext()) array[indices.next()] = iterator.next(); return array; } /** * Converts an iterator to an object array using the given one. Throws an * {@link java.lang.ArrayIndexOutOfBoundsException ArrayIndexOutOfBoundsException} * if the number of the iterator's elements is larger than the length of * the given array. * * @param <E> the type of the elements returned by the given iterator. * @param iterator the input iterator. * @param array the array into which the elements of the given iteration * are to be stored. * @return the object array containing the iterator's elements. * @throws java.lang.ArrayIndexOutOfBoundsException if the given array is * not long enough. */ public static <E> E[] toArray(Iterator<? extends E> iterator, E[] array) { for (int index = 0; iterator.hasNext(); array[index++] = iterator.next()); return array; } /** * Converts an iterator to an object array whose length is equal to the * number of the iterator's elements. When the iterator contains more * elements than the array is able to store, a new array of the same * component type is created. * * @param <E> the type of the elements returned by the given iterator. * @param iterator the input iterator. * @param array the array into which the elements of the given iteration * are to be stored. * @return an object array containing the iterator's elements. */ public static <E> E[] toFittingArray(Iterator<? extends E> iterator, E[] array) { ArrayResizer resizer = new ArrayResizer(0.5, 0); int size = array.length; for (int index = 0; iterator.hasNext(); array[index++] = iterator.next()) if (index >= size) array = resizer.resize(array, size = index+1); return new ArrayResizer(1, 1).resize(array, size); } /** * Converts an iterator to an object array whose length is determined by * the largest index. Stops as soon as one iterator is exhausted. When the * iterator contains more elements than the array is able to store, a new * array of the same component type is created. * * @param <E> the type of the elements returned by the given iterator. * @param iterator the input iterator. * @param array the array into which the elements of the given iteration * are to be stored. * @param indices each index determines where to store the corresponding * iterator element. * @return an object array of the iterator's elements following the order * defined by the iterator <tt>indices</tt>. */ public static <E> E[] toFittingArray(Iterator<? extends E> iterator, E[] array, Iterator<Integer> indices) { ArrayResizer resizer = new ArrayResizer(0.5, 0); int size = array.length; for (int index; iterator.hasNext() && indices.hasNext(); array[index] = iterator.next()) if ((index = indices.next()) >= size) array = resizer.resize(array, size = index+1); return new ArrayResizer(1, 1).resize(array, size); } /** * Converts an iterator to a {@link java.util.Map map}. Partitions the * iterator's elements according to the result of the unary function * <code>getKey</code>. Each partition is the value of its corresponding * map entry and is implemented as a collection. * * @param <E> the type of the elements returned by the given iterator. * @param <K> the type of the keys used for mapping the elements of the * given iterator. * @param iterator the input iterator. * @param getKey unary function that determines the key for an iterator's * element. * @param map the map used to store the partitions. * @param newCollection creates a new collection to store the elements of a * new partition. * @return the map implementing the partition of the iterator's elements. */ public static <E, K> Map<? super K, Collection<E>> toMap(Iterator<? extends E> iterator, Function<? super E, ? extends K> getKey, Map<? super K, Collection<E>> map, Function<?, ? extends Collection<E>> newCollection) { while (iterator.hasNext()) { E next = iterator.next(); K key = getKey.invoke(next); Collection<E> collection = map.get(key); if (collection == null) map.put(key, collection = newCollection.invoke()); collection.add(next); } return map; } /** * Converts an iterator to a {@link java.util.Map map}. Partitions the * iterator's elements according to the result of the unary function * <code>getKey</code>. Each partition is the value of its corresponding * map entry and is implemented as a * {@link java.util.LinkedList linked list}. * * @param <E> the type of the elements returned by the given iterator. * @param <K> the type of the keys used for mapping the elements of the * given iterator. * @param iterator the input iterator. * @param getKey unary function that determines the key for an iterator's * element. * @param map the map used to store the partitions. * @return the map implementing the partition of the iterator's elements. */ public static <E, K> Map<? super K, Collection<E>> toMap(Iterator<? extends E> iterator, Function<? super E, ? extends K> getKey, Map<? super K, Collection<E>> map) { return toMap( iterator, getKey, map, new AbstractFunction<Object, LinkedList<E>>() { @Override public LinkedList<E> invoke() { return new LinkedList<E>(); } } ); } /** * Converts an iterator to a {@link java.util.HashMap hash map}. Partitions * the iterator's elements according to the result of the unary function * <code>getKey</code>. Each partition is the value part of its * corresponding map entry and is implemented as a collection. * * @param <E> the type of the elements returned by the given iterator. * @param <K> the type of the keys used for mapping the elements of the * given iterator. * @param iterator the input iterator. * @param getKey unary function that determines the key for an iterator's * element. * @param newCollection creates a new collection to store the elements of a * new partition. * @return the map implementing the partition of the iterator's elements. */ public static <E, K> Map<? super K, Collection<E>> toMap(Iterator<? extends E> iterator, Function<? super E, ? extends K> getKey, Function<?, ? extends Collection<E>> newCollection) { return toMap(iterator, getKey, new HashMap<K, Collection<E>>(), newCollection); } /** * Converts an iterator to a {@link java.util.HashMap hash map}. Partitions * the iterator's elements according to the result of the function * <code>getKey</code>. Each partition is the value part of its * corresponding map entry and is implemented as a * {@link java.util.LinkedList linked list}. * * @param <E> the type of the elements returned by the given iterator. * @param <K> the type of the keys used for mapping the elements of the * given iterator. * @param iterator the input iterator. * @param getKey unary function that determines the key for an iterator's * element. * @return the map implementing the partition of the iterator's elements. */ public static <E, K> Map<? super K, Collection<E>> toMap(Iterator<? extends E> iterator, Function<? super E, ? extends K> getKey) { return toMap(iterator, getKey, new HashMap<K, Collection<E>>()); } /** * Wraps the given {@link java.util.Iterator iterator} to a * {@link xxl.core.cursors.Cursor cursor}. If the given iterator is already * a cursor, it is returned unchanged. The current implementation is as * follows: * <code><pre> * return iterator instanceof Cursor ? * (Cursor<E>)iterator : * new IteratorCursor<E>(iterator); * </pre></code> * * @param <E> the type of the elements returned by the given iterator. * @param iterator the iterator to be wrapped. * @return a cursor wrapping the given iterator. * @see xxl.core.cursors.wrappers.IteratorCursor */ public static <E> Cursor<E> wrap(Iterator<E> iterator) { return iterator instanceof Cursor ? (Cursor<E>)iterator : new IteratorCursor<E>(iterator); } /** * Wraps a given {@link java.util.Iterator iterator} (keep in mind that a * {@link xxl.core.cursors.Cursor cursor} is also an iterator) to a * {@link xxl.core.cursors.MetaDataCursor meta data cursor}. In that way an * ordinary iterator can be enriched by meta data that is provided via the * {@link xxl.core.cursors.MetaDataCursor#getMetaData() getMetaData} * method. * * @param <E> the type of the elements returned by the given iterator. * @param <M> the type of the given meta data object. * @param iterator the iterator to be enriched by meta data information. * @param metaData an object containing the meta data information. * @return a meta data cursor enriching the given iterator by some meta * data information. */ public static <E, M> MetaDataCursor<E, M> wrapToMetaDataCursor(Iterator<E> iterator, final M metaData) { return new AbstractMetaDataCursor<E, M>(iterator) { @Override public M getMetaData() { return metaData; } }; } /** * Extends {@link FileInputCursor} with simple reset method; * the reset method closes internal data stream from the file, and reopens it. * @param converter * @param file * @return */ public static <E> Cursor<? extends E> resetableFileInputCursor(Converter<? extends E> converter, final File file, final int bufferSize){ return new FileInputCursor<E>(converter, file, bufferSize){ @Override public boolean supportsReset() { return true; } @Override public void reset() throws UnsupportedOperationException { super.reset(); try { try { input.close(); // close previous }catch (IOException e) {} input = new DataInputStream( new BufferedInputStream( new FileInputStream(file), bufferSize ) ); } catch (IOException ie) { throw new WrappingRuntimeException(ie); } } }; } /** * Extends {@link FileInputCursor} with simple reset method; * the reset method closes internal data stream from the file, and reopens it. * @param converter * @param file * @return */ public static <E> Cursor<? extends E> resetableFileInputCursor(Converter<? extends E> converter, final File file){ return resetableFileInputCursor(converter, file, 4096); } }