All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.neo4j.helpers.collection.IteratorUtil Maven / Gradle / Ivy

/*
 * Copyright (c) 2002-2015 "Neo Technology,"
 * Network Engine for Objects in Lund AB [http://neotechnology.com]
 *
 * This file is part of Neo4j.
 *
 * Neo4j is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
package org.neo4j.helpers.collection;

import java.io.File;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;

import org.neo4j.collection.primitive.PrimitiveIntIterator;
import org.neo4j.collection.primitive.PrimitiveLongIterator;
import org.neo4j.function.Predicate;
import org.neo4j.function.Predicates;
import org.neo4j.graphdb.Resource;
import org.neo4j.graphdb.ResourceIterable;
import org.neo4j.graphdb.ResourceIterator;
import org.neo4j.helpers.CloneableInPublic;
import org.neo4j.helpers.Function;
import org.neo4j.helpers.Pair;
import org.neo4j.kernel.impl.util.PrimitiveLongResourceIterator;

import static java.util.EnumSet.allOf;

import static org.neo4j.helpers.collection.Iterables.map;

/**
 * Contains common functionality regarding {@link Iterator}s and
 * {@link Iterable}s.
 */
public abstract class IteratorUtil
{
    /**
     * Returns the given iterator's first element or {@code null} if no
     * element found.
     *
     * @param  the type of elements in {@code iterator}.
     * @param iterator the {@link Iterator} to get elements from.
     * @return the first element in the {@code iterator}, or {@code null} if no
     * element found.
     */
    public static  T firstOrNull( Iterator iterator )
    {
        return iterator.hasNext() ? iterator.next() : null;
    }

    /**
     * Returns the given iterator's first element. If no element is found a
     * {@link NoSuchElementException} is thrown.
     *
     * @param  the type of elements in {@code iterator}.
     * @param iterator the {@link Iterator} to get elements from.
     * @return the first element in the {@code iterator}.
     * @throws NoSuchElementException if no element found.
     */
    public static  T first( Iterator iterator )
    {
        return assertNotNull( iterator, firstOrNull( iterator ) );
    }

    /**
     * Returns the given iterator's last element or {@code null} if no
     * element found.
     *
     * @param  the type of elements in {@code iterator}.
     * @param iterator the {@link Iterator} to get elements from.
     * @return the last element in the {@code iterator}, or {@code null} if no
     * element found.
     */
    public static  T lastOrNull( Iterator iterator )
    {
        T result = null;
        while ( iterator.hasNext() )
        {
            result = iterator.next();
        }
        return result;
    }

    /**
     * Returns the given iterator's last element. If no element is found a
     * {@link NoSuchElementException} is thrown.
     *
     * @param  the type of elements in {@code iterator}.
     * @param iterator the {@link Iterator} to get elements from.
     * @return the last element in the {@code iterator}.
     * @throws NoSuchElementException if no element found.
     */
    public static  T last( Iterator iterator )
    {
        return assertNotNull( iterator, lastOrNull( iterator ) );
    }

    /**
     * Returns the given iterator's single element or {@code null} if no
     * element found. If there is more than one element in the iterator a
     * {@link NoSuchElementException} will be thrown.
     *
     * If the {@code iterator} implements {@link Resource} it will be {@link Resource#close() closed}
     * in a {@code finally} block after the single item has been retrieved, or failed to be retrieved.
     *
     * @param  the type of elements in {@code iterator}.
     * @param iterator the {@link Iterator} to get elements from.
     * @return the single element in {@code iterator}, or {@code null} if no
     * element found.
     * @throws NoSuchElementException if more than one element was found.
     */
    public static  T singleOrNull( Iterator iterator )
    {
        return single( iterator, null );
    }

    /**
     * Returns the given iterator's single element. If there are no elements
     * or more than one element in the iterator a {@link NoSuchElementException}
     * will be thrown.
     *
     * If the {@code iterator} implements {@link Resource} it will be {@link Resource#close() closed}
     * in a {@code finally} block after the single item has been retrieved, or failed to be retrieved.
     *
     * @param  the type of elements in {@code iterator}.
     * @param iterator the {@link Iterator} to get elements from.
     * @return the single element in the {@code iterator}.
     * @throws NoSuchElementException if there isn't exactly one element.
     */
    public static  T single( Iterator iterator )
    {
        return assertNotNull( iterator, singleOrNull( iterator ) );
    }

    /**
     * Returns the iterator's n:th item from the end of the iteration.
     * If the iterator has got less than n-1 items in it
     * {@link NoSuchElementException} is thrown.
     *
     * @param  the type of elements in {@code iterator}.
     * @param iterator the {@link Iterator} to get elements from.
     * @param n the n:th item from the end to get.
     * @return the iterator's n:th item from the end of the iteration.
     * @throws NoSuchElementException if the iterator contains less than n-1 items.
     */
    public static  T fromEnd( Iterator iterator, int n )
    {
        return assertNotNull( iterator, fromEndOrNull( iterator, n ) );
    }

    /**
     * Returns the iterator's n:th item from the end of the iteration.
     * If the iterator has got less than n-1 items in it {@code null} is returned.
     *
     * @param  the type of elements in {@code iterator}.
     * @param iterator the {@link Iterator} to get elements from.
     * @param n the n:th item from the end to get.
     * @return the iterator's n:th item from the end of the iteration,
     * or {@code null} if the iterator doesn't contain that many items.
     */
    public static  T fromEndOrNull( Iterator iterator, int n )
    {
        Deque trail = new ArrayDeque<>( n );
        while ( iterator.hasNext() )
        {
            if ( trail.size() > n )
            {
                trail.removeLast();
            }
            trail.addFirst( iterator.next() );
        }
        return trail.size() == n + 1 ? trail.getLast() : null;
    }

    /**
     * Iterates over the full iterators, and checks equality for each item in them. Note that this
     * will consume the iterators.
     * 
     * @param first the first iterator
     * @param other the other iterator
     * @return {@code true} if all items are equal; otherwise 
     */
    public static boolean iteratorsEqual( Iterator first, Iterator other )
    {
        while ( true )
        {
            if ( first.hasNext() && other.hasNext() )
            {
                if ( !first.next().equals( other.next() ) )
                {
                    return false;
                }
            }
            else
            {
                return first.hasNext() == other.hasNext();
            }
        }
    }

    private static  T assertNotNull( Iterator iterator, T result )
    {
        if ( result == null )
        {
            throw new NoSuchElementException( "No element found in " + iterator );
        }
        return result;
    }

    /**
     * Returns the given iterable's first element or {@code null} if no
     * element found.
     *
     * @param  the type of elements in {@code iterable}.
     * @param iterable the {@link Iterable} to get elements from.
     * @return the first element in the {@code iterable}, or {@code null} if no
     * element found.
     */
    public static  T firstOrNull( Iterable iterable )
    {
        return firstOrNull( iterable.iterator() );
    }

    /**
     * Returns the given iterable's first element. If no element is found a
     * {@link NoSuchElementException} is thrown.
     *
     * @param  the type of elements in {@code iterable}.
     * @param iterable the {@link Iterable} to get elements from.
     * @return the first element in the {@code iterable}.
     * @throws NoSuchElementException if no element found.
     */
    public static  T first( Iterable iterable )
    {
        return first( iterable.iterator() );
    }

    /**
     * Returns the given iterable's last element or {@code null} if no
     * element found.
     *
     * @param  the type of elements in {@code iterable}.
     * @param iterable the {@link Iterable} to get elements from.
     * @return the last element in the {@code iterable}, or {@code null} if no
     * element found.
     */
    public static  T lastOrNull( Iterable iterable )
    {
        return lastOrNull( iterable.iterator() );
    }

    /**
     * Returns the given iterable's last element. If no element is found a
     * {@link NoSuchElementException} is thrown.
     *
     * @param  the type of elements in {@code iterable}.
     * @param iterable the {@link Iterable} to get elements from.
     * @return the last element in the {@code iterable}.
     * @throws NoSuchElementException if no element found.
     */
    public static  T last( Iterable iterable )
    {
        return last( iterable.iterator() );
    }

    /**
     * Returns the given iterable's single element or {@code null} if no
     * element found. If there is more than one element in the iterable a
     * {@link NoSuchElementException} will be thrown.
     *
     * If the {@link Iterable#iterator() iterator} created by the {@code iterable} implements {@link Resource}
     * it will be {@link Resource#close() closed} in a {@code finally} block after the single item
     * has been retrieved, or failed to be retrieved.
     *
     * @param  the type of elements in {@code iterable}.
     * @param iterable the {@link Iterable} to get elements from.
     * @return the single element in {@code iterable}, or {@code null} if no
     * element found.
     * @throws NoSuchElementException if more than one element was found.
     */
    public static  T singleOrNull( Iterable iterable )
    {
        return singleOrNull( iterable.iterator() );
    }

    /**
     * Returns the given iterable's single element. If there are no elements
     * or more than one element in the iterable a {@link NoSuchElementException}
     * will be thrown.
     *
     * If the {@link Iterable#iterator() iterator} created by the {@code iterable} implements {@link Resource}
     * it will be {@link Resource#close() closed} in a {@code finally} block after the single item
     * has been retrieved, or failed to be retrieved.
     *
     * @param  the type of elements in {@code iterable}.
     * @param iterable the {@link Iterable} to get elements from.
     * @return the single element in the {@code iterable}.
     * @throws NoSuchElementException if there isn't exactly one element.
     */
    public static  T single( Iterable iterable )
    {
        return single( iterable.iterator() );
    }

    /**
     * Returns the given iterable's single element or {@code itemIfNone} if no
     * element found. If there is more than one element in the iterable a
     * {@link NoSuchElementException} will be thrown.
     *
     * If the {@link Iterable#iterator() iterator} created by the {@code iterable} implements {@link Resource}
     * it will be {@link Resource#close() closed} in a {@code finally} block after the single item
     * has been retrieved, or failed to be retrieved.
     *
     * @param  the type of elements in {@code iterable}.
     * @param iterable the {@link Iterable} to get elements from.
     * @param itemIfNone item to use if none is found
     * @return the single element in {@code iterable}, or {@code null} if no
     * element found.
     * @throws NoSuchElementException if more than one element was found.
     */
    public static  T single( Iterable iterable, T itemIfNone )
    {
        return single( iterable.iterator(), itemIfNone );
    }

    /**
     * Returns the given iterator's single element or {@code itemIfNone} if no
     * element found. If there is more than one element in the iterator a
     * {@link NoSuchElementException} will be thrown.
     *
     * If the {@code iterator} implements {@link Resource} it will be {@link Resource#close() closed}
     * in a {@code finally} block after the single item has been retrieved, or failed to be retrieved.
     *
     * @param  the type of elements in {@code iterator}.
     * @param iterator the {@link Iterator} to get elements from.
     * @param itemIfNone item to use if none is found
     * @return the single element in {@code iterator}, or {@code itemIfNone} if no
     * element found.
     * @throws NoSuchElementException if more than one element was found.
     */
    public static  T single( Iterator iterator, T itemIfNone )
    {
        try
        {
            T result = iterator.hasNext() ? iterator.next() : itemIfNone;
            if ( iterator.hasNext() )
            {
                throw new NoSuchElementException( "More than one element in " + iterator + ". First element is '"
                        + result + "' and the second element is '" + iterator.next() + "'" );
            }
            return result;
        }
        finally
        {
            if ( iterator instanceof Resource )
            {
                ((Resource) iterator).close();
            }
        }
    }

    /**
     * Returns the iterator's n:th item from the end of the iteration.
     * If the iterator has got less than n-1 items in it
     * {@link NoSuchElementException} is thrown.
     *
     * @param  the type of elements in {@code iterator}.
     * @param iterable the {@link Iterable} to get elements from.
     * @param n the n:th item from the end to get.
     * @return the iterator's n:th item from the end of the iteration.
     * @throws NoSuchElementException if the iterator contains less than n-1 items.
     */
    public static  T fromEnd( Iterable iterable, int n )
    {
        return fromEnd( iterable.iterator(), n );
    }

    /**
     * Adds all the items in {@code iterator} to {@code collection}.
     * @param  the type of {@link Collection} to add to items to.
     * @param  the type of items in the collection and iterator.
     * @param iterator the {@link Iterator} to grab the items from.
     * @param collection the {@link Collection} to add the items to.
     * @return the {@code collection} which was passed in, now filled
     * with the items from {@code iterator}.
     */
    public static ,T> C addToCollection( Iterator iterator,
            C collection )
    {
        while ( iterator.hasNext() )
        {
            collection.add( iterator.next() );
        }
        return collection;
    }

    /**
     * Adds all the items in {@code iterator} to {@code collection}.
     * @param  the type of {@link Collection} to add to items to.
     * @param iterator the {@link Iterator} to grab the items from.
     * @param collection the {@link Collection} to add the items to.
     * @return the {@code collection} which was passed in, now filled
     * with the items from {@code iterator}.
     */
    public static > C addToCollection( PrimitiveLongIterator iterator, C collection )
    {
        while ( iterator.hasNext() )
        {
            collection.add( iterator.next() );
        }
        return collection;
    }

    /**
     * Adds all the items in {@code iterator} to {@code collection}.
     * @param  the type of {@link Collection} to add to items to.
     * @param iterator the {@link Iterator} to grab the items from.
     * @param collection the {@link Collection} to add the items to.
     * @return the {@code collection} which was passed in, now filled
     * with the items from {@code iterator}.
     */
    public static > C addToCollection( PrimitiveIntIterator iterator, C collection )
    {
        while ( iterator.hasNext() )
        {
            collection.add( iterator.next() );
        }
        return collection;
    }

    /**
     * Adds all the items in {@code iterator} to {@code collection}.
     * @param  the type of {@link Collection} to add to items to.
     * @param  the type of items in the collection and iterator.
     * @param iterator the {@link Iterator} to grab the items from.
     * @param collection the {@link Collection} to add the items to.
     * @return the {@code collection} which was passed in, now filled
     * with the items from {@code iterator}.
     */
    public static ,T> C addToCollectionUnique( Iterator iterator,
            C collection )
    {
        while ( iterator.hasNext() )
        {
            addUnique( collection, iterator.next() );
        }
        return collection;
    }

    private static > void addUnique( C collection, T item )
    {
        if ( !collection.add( item ) )
        {
            throw new IllegalStateException( "Encountered an already added item:" + item +
                    " when adding items uniquely to a collection:" + collection );
        }
    }

    /**
     * Adds all the items in {@code iterator} to {@code collection}.
     * @param  the type of {@link Collection} to add to items to.
     * @param  the type of items in the collection and iterator.
     * @param iterable the {@link Iterator} to grab the items from.
     * @param collection the {@link Collection} to add the items to.
     * @return the {@code collection} which was passed in, now filled
     * with the items from {@code iterator}.
     */
    public static ,T> C addToCollection( Iterable iterable,
            C collection )
    {
        return addToCollection( iterable.iterator(), collection );
    }

    /**
     * Adds all the items in {@code iterator} to {@code collection}.
     * @param  the type of {@link Collection} to add to items to.
     * @param  the type of items in the collection and iterator.
     * @param iterable the {@link Iterator} to grab the items from.
     * @param collection the {@link Collection} to add the items to.
     * @return the {@code collection} which was passed in, now filled
     * with the items from {@code iterator}.
     */
    public static ,T> C addToCollectionUnique( Iterable iterable,
            C collection )
    {
        return addToCollectionUnique( iterable.iterator(), collection );
    }

    /**
     * Convenience method for looping over an {@link Iterator}. Converts the
     * {@link Iterator} to an {@link Iterable} by wrapping it in an
     * {@link Iterable} that returns the {@link Iterator}. It breaks the
     * contract of {@link Iterable} in that it returns the supplied iterator
     * instance for each call to {@code iterator()} on the returned
     * {@link Iterable} instance. This method exists to make it easy to use an
     * {@link Iterator} in a for-loop.
     *
     * @param  the type of items in the iterator.
     * @param iterator the iterator to expose as an {@link Iterable}.
     * @return the supplied iterator posing as an {@link Iterable}.
     */
    public static  Iterable loop( final Iterator iterator )
    {
        return new Iterable()
        {
            @Override
            public Iterator iterator()
            {
                return iterator;
            }
        };
    }

    /**
     * Exposes {@code iterator} as an {@link Iterable}. It breaks the contract
     * of {@link Iterable} in that it returns the supplied iterator instance for
     * each call to {@code iterator()} on the returned {@link Iterable}
     * instance. This method mostly exists to make it easy to use an
     * {@link Iterator} in a for-loop.
     *
     * @param  the type of items in the iterator.
     * @param iterator the iterator to expose as an {@link Iterable}.
     * @return the supplied iterator posing as an {@link Iterable}.
     */
    //@Deprecated * @deprecated use {@link #loop(Iterator) the loop method} instead.
    public static  Iterable asIterable( final Iterator iterator )
    {
        return loop( iterator );
    }

    public static  int count( Iterator iterator )
    {
        return count( iterator, Predicates.alwaysTrue() );
    }

    /**
     * Counts the number of filtered in the {@code iterator} by looping
     * through it.
     * @param  the type of items in the iterator.
     * @param iterator the {@link Iterator} to count items in.
     * @param filter the filter to test items against
     * @return the number of filtered items found in {@code iterator}.
     */
    public static  int count( Iterator iterator, Predicate filter )
    {
        int result = 0;
        while ( iterator.hasNext() )
        {
            if ( filter.test( iterator.next() ) )
            {
                result++;
            }
        }
        return result;
    }

    /**
     * Counts the number of items in the {@code iterator} by looping
     * through it.
     * @param  the type of items in the iterator.
     * @param iterable the {@link Iterable} to count items in.
     * @return the number of items found in {@code iterable}.
     */
    public static  int count( Iterable iterable )
    {
        return count( iterable, Predicates.alwaysTrue() );
    }

    /**
     * Counts the number of items in the {@code iterable} by looping through it.
     *
     * @param  the type of items in the iterator.
     * @param iterable the {@link Iterable} to count items in.
     * @param filter the filter to apply
     * @return the number of items found in {@code iterator}.
     */
    public static  int count( Iterable iterable, org.neo4j.helpers.Predicate filter )
    {
        return count( iterable.iterator(), org.neo4j.helpers.Predicates.upgrade( filter ) );
    }

    /**
     * Counts the number of filtered items in the {@code iterable} by looping through it.
     *
     * @param  the type of items in the iterator.
     * @param iterable the {@link Iterable} to count items in.
     * @param filter the filter to test items against
     * @return the number of found in {@code iterable}.
     */
    public static  int count( Iterable iterable, Predicate filter )
    {
        return count( iterable.iterator(), filter );
    }

    /**
     * Creates a collection from an iterable.
     *
     * @param iterable The iterable to create the collection from.
     * @param  The generic type of both the iterable and the collection.
     * @return a collection containing all items from the iterable.
     */
    public static  Collection asCollection( Iterable iterable )
    {
        return addToCollection( iterable, new ArrayList() );
    }
    public static  Collection asCollection( Iterator iterable )
    {
        return addToCollection( iterable, new ArrayList() );
    }

    public static  List asList( Iterator iterator )
    {
        return addToCollection( iterator, new ArrayList() );
    }

    public static  List asList( Iterable iterator )
    {
        return addToCollection( iterator, new ArrayList() );
    }

    public static List asList( PrimitiveLongIterator iterator )
    {
        List out = new ArrayList<>();
        while(iterator.hasNext())
        {
            out.add(iterator.next());
        }
        return out;
    }

    public static List asList( PrimitiveIntIterator iterator )
    {
        List out = new ArrayList<>();
        while(iterator.hasNext())
        {
            out.add(iterator.next());
        }
        return out;
    }

    public static  Map asMap( Iterable> pairs )
    {
        Map map = new HashMap<>();
        for (Pair pair: pairs) {
            map.put(pair.first(), pair.other());
        }
        return map;
    }

    /**
     * Creates a {@link Set} from an {@link Iterable}.
     *
     * @param iterable The items to create the set from.
     * @param  The generic type of items.
     * @return a set containing all items from the {@link Iterable}.
     */
    public static  Set asSet( Iterable iterable )
    {
        return addToCollection( iterable, new HashSet() );
    }

    public static  Set asSet( Iterator iterator )
    {
        return addToCollection( iterator, new HashSet() );
    }

    /**
     * Creates a {@link Set} from an {@link Iterable}.
     *
     * @param iterable The items to create the set from.
     * @param  The generic type of items.
     * @return a set containing all items from the {@link Iterable}.
     */
    public static  Set asUniqueSet( Iterable iterable )
    {
        return addToCollectionUnique( iterable, new HashSet() );
    }

    /**
     * Creates a {@link Set} from an array of items.
     *
     * @param items the items to add to the set.
     * @param  the type of the items
     * @return the {@link Set} containing the items.
     */
    @SafeVarargs
    public static  Set asSet( T... items )
    {
        return new HashSet<>( Arrays.asList( items ) );
    }

    public static  Set emptySetOf( @SuppressWarnings("unused"/*just used as a type marker*/) Class type )
    {
        return Collections.emptySet();
    }

    public static  List emptyListOf( @SuppressWarnings("unused"/*just used as a type marker*/) Class type )
    {
        return Collections.emptyList();
    }

    /**
     * Alias for asSet()
     * 
     * @param items the items to add to the set.
     * @param  the type of the items
     * @return the {@link Set} containing the items.
     */
    @SafeVarargs
    public static  Set set( T... items)
    {
        return asSet(items);
    }

    /**
     * Creates a {@link Set} from an array of items.
     *
     * @param items the items to add to the set.
     * @param  the type of the items
     * @return the {@link Set} containing the items.
     */
    @SafeVarargs
    public static  Set asUniqueSet( T... items )
    {
        HashSet set = new HashSet<>();
        for ( T item : items )
        {
            addUnique( set, item );
        }
        return set;
    }

    /**
     * Creates a {@link Set} from an array of items.
     *
     * @param items the items to add to the set.
     * @param  the type of the items
     * @return the {@link Set} containing the items.
     */
    public static  Set asUniqueSet( Iterator items )
    {
        HashSet set = new HashSet<>();
        while( items.hasNext() )
        {
            addUnique( set, items.next() );
        }
        return set;
    }

    /**
     * Function for converting Enum to String
     */
    @SuppressWarnings( "rawtypes" )
    public final static Function ENUM_NAME = new Function()
    {
        @Override
        public String apply( Enum from )
        {
            return from.name();
        }
    };

    /**
     * Converts an {@link Iterable} of enums to {@link Set} of their names.
     *
     * @param enums the enums to convert.
     * @return the set of enum names
     */
    @SuppressWarnings( "rawtypes" )
    public static Set asEnumNameSet( Iterable enums )
    {
        return asSet( map( ENUM_NAME, enums ) );
    }

    /**
     * Converts an enum class to to {@link Set} of the names of all valid enum values
     *
     * @param clazz enum class
     * @param  enum type bound
     * @return the set of enum names
     */
    public static > Set asEnumNameSet( Class clazz)
    {
        return asSet( map( ENUM_NAME, allOf( clazz ) ) );
    }

    /**
     * Creates an {@link Iterable} for iterating over the lines of a text file.
     * @param file the file to get the lines for.
     * @param encoding the encoding of the file
     * @return an {@link Iterable} for iterating over the lines of a text file.
     */
    public static ClosableIterable asIterable( final File file, final String encoding )
    {
        return new ClosableIterable()
        {
            private ClosableIterator mostRecentIterator;

            @Override
            public Iterator iterator()
            {
                try
                {
                    if ( mostRecentIterator != null )
                    {
                        mostRecentIterator.close();
                    }
                    mostRecentIterator = asIterator( file, encoding );
                    return mostRecentIterator;
                }
                catch ( IOException e )
                {
                    throw new RuntimeException( e );
                }
            }

            @Override
            public void close()
            {
                if ( mostRecentIterator != null )
                {
                    mostRecentIterator.close();
                }
            }
        };
    }

    /**
     * Creates an {@link Iterator} for iterating over the lines of a text file.
     * The opened file is closed if an exception occurs during reading or when
     * the files has been read through all the way.
     * @param file the file to get the lines for.
     * @param encoding to be used for reading the file
     * @return an {@link Iterator} for iterating over the lines of a text file.
     * @throws IOException from underlying I/O operations
     */
    public static ClosableIterator asIterator( File file, String encoding ) throws IOException
    {
        return new LinesOfFileIterator( file, encoding );
    }

    public static Iterable asIterable( final long... array )
    {
        return new Iterable()
        {
            @Override
            public Iterator iterator()
            {
                return asIterator( array );
            }
        };
    }

    @SafeVarargs
    public static  Iterable asIterable( final T... array )
    {
        return new Iterable()
        {
            @Override
            public Iterator iterator()
            {
                return IteratorUtil.iterator( array );
            }
        };
    }

    public static Iterator asIterator( final long... array )
    {
        return new PrefetchingIterator()
        {
            private int index;

            @Override
            protected Long fetchNextOrNull()
            {
                try
                {
                    return index < array.length ? array[index] : null;
                }
                finally
                {
                    index++;
                }
            }
        };
    }

    @SafeVarargs
    public static  Iterator asIterator( final int maxItems, final T... array )
    {
        return new PrefetchingIterator()
        {
            private int index;

            @Override
            protected T fetchNextOrNull()
            {
                try
                {
                    return index < array.length && index < maxItems ? array[index] : null;
                }
                finally
                {
                    index++;
                }
            }
        };
    }

    public static  Iterator iterator( final T item )
    {
        if ( item == null )
        {
            return emptyIterator();
        }

        return new Iterator()
        {
            T myItem = item;

            @Override
            public boolean hasNext()
            {
                return myItem != null;
            }

            @Override
            public T next()
            {
                if ( !hasNext() )
                {
                    throw new NoSuchElementException();
                }
                T toReturn = myItem;
                myItem = null;
                return toReturn;
            }

            @Override
            public void remove()
            {
                throw new UnsupportedOperationException();
            }
        };
    }

    @SafeVarargs
    public static  Iterator iterator( T ... items )
    {
        return asIterator( items.length, items );
    }

    @SafeVarargs
    public static  Iterator iterator( int maxItems, T ... items )
    {
        return asIterator( maxItems, items );
    }

    @SuppressWarnings( "rawtypes" )
    private static final ResourceIterator EMPTY_ITERATOR = new ResourceIterator()
    {
        @Override
        public boolean hasNext()
        {
            return false;
        }

        @Override
        public Object next()
        {
            throw new NoSuchElementException();
        }

        @Override
        public void remove()
        {
            throw new UnsupportedOperationException();
        }

        @Override
        public void close()
        {
            // do nothing
        }
    };

    @SuppressWarnings( "unchecked" )
    public static  ResourceIterator emptyIterator()
    {
        return EMPTY_ITERATOR;
    }

    public static  boolean contains( Iterator iterator, T item )
    {
        try
        {
            for ( T element : loop( iterator ) )
            {
                if ( item == null ? element == null : item.equals( element ) )
                {
                    return true;
                }
            }
            return false;
        }
        finally
        {
            if ( iterator instanceof ResourceIterator )
            {
                ((ResourceIterator) iterator).close();
            }
        }
    }

    public static  Iterable cloned( Iterable items, final Class itemClass )
    {
        return Iterables.map( new Function()
        {
            @Override
            public T apply( T from )
            {
                return itemClass.cast( from.clone() );
            }
        }, items );
    }

    public static  ResourceIterator asResourceIterator( final Iterator iterator )
    {
        return new WrappingResourceIterator<>( iterator );
    }

    @SuppressWarnings("UnusedDeclaration"/*Useful when debugging in tests, but not used outside of debugging sessions*/)
    public static Iterator toJavaIterator( final PrimitiveLongIterator primIterator )
    {
        return new Iterator()
        {
            @Override
            public boolean hasNext()
            {
                return primIterator.hasNext();
            }

            @Override
            public Long next()
            {
                return primIterator.next();
            }

            @Override
            public void remove()
            {
                throw new UnsupportedOperationException(  );
            }
        };
    }

    public static List primitivesList( PrimitiveLongIterator iterator )
    {
        ArrayList result = new ArrayList<>();
        while ( iterator.hasNext() )
        {
            result.add( iterator.next() );
        }
        return result;
    }

    public static Set asSet( PrimitiveLongIterator iterator )
    {
        return internalAsSet( iterator, false );
    }

    private static Set internalAsSet( PrimitiveLongIterator iterator, boolean allowDuplicates )
    {
        Set set = new HashSet<>();
        while ( iterator.hasNext() )
        {
            long value = iterator.next();
            if ( !set.add( value ) && !allowDuplicates )
            {
                throw new IllegalStateException( "Duplicates found. Tried to add " + value + " to " + set );
            }
        }
        return set;
    }

    public static Set asSet( PrimitiveIntIterator iterator )
    {
        Set set = new HashSet<>();
        while ( iterator.hasNext() )
        {
            set.add( iterator.next() );
        }
        return set;
    }

    /**
     * Creates a {@link Set} from an array of iterator.
     *
     * @param iterator the iterator to add to the set.
     * @return the {@link Set} containing the iterator.
     */
    public static Set asUniqueSet( PrimitiveLongIterator iterator )
    {
        HashSet set = new HashSet<>();
        while ( iterator.hasNext() )
        {
            addUnique( set, iterator.next() );
        }
        return set;
    }

    public static PrimitiveLongResourceIterator resourceIterator( final PrimitiveLongIterator iterator,
            final Resource resource )
    {
        return new PrimitiveLongResourceIterator()
        {
            @Override
            public void close()
            {
                if ( resource != null )
                {
                    resource.close();
                }
            }

            @Override
            public long next()
            {
                return iterator.next();
            }

            @Override
            public boolean hasNext()
            {
                return iterator.hasNext();
            }
        };
    }

    public static  ResourceIterator resourceIterator( final Iterator iterator, final Resource resource )
    {
        return new PrefetchingResourceIterator()
        {
            @Override
            public void close()
            {
                resource.close();
            }

            @Override
            protected T fetchNextOrNull()
            {
                return iterator.hasNext() ? iterator.next() : null;
            }
        };
    }

    public static  ResourceIterable resourceIterable( final Iterable iterable )
    {
        return new ResourceIterable()
        {
            @Override
            public ResourceIterator iterator()
            {
                return resourceIterator( iterable.iterator(), Resource.EMPTY );
            }
        };
    }

    @SafeVarargs
    public static  T[] array( T... items )
    {
        return items;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy