org.neo4j.helpers.collection.IteratorUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of neo4j-kernel Show documentation
Show all versions of neo4j-kernel Show documentation
Neo4j kernel is a lightweight, embedded Java database designed to
store data structured as graphs rather than tables. For more
information, see http://neo4j.org.
/**
* Copyright (c) 2002-2013 "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 static java.util.Arrays.asList;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
/**
* 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 {@link 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 {@link 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.
*
* @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 {@link NoSuchElementException} if more than one element was
* found.
*/
public static T singleOrNull( Iterator iterator )
{
T result = iterator.hasNext() ? iterator.next() : null;
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;
}
/**
* 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.
*
* @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 {@link 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
* @param other
* @return
*/
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 {@link 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 {@link 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.
*
* @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 {@link 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.
*
* @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 {@link NoSuchElementException} if there isn't exactly one
* element.
*/
public static T single( Iterable iterable )
{
return single( iterable.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 {@code null} is returned.
*
* @param the type of elements in {@code iterator}.
* @param iterable the {@link Iterable} to get elements from.
* @param countFromEnd 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( Iterable iterable, int countFromEnd )
{
return fromEndOrNull( iterable.iterator(), countFromEnd );
}
/**
* 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 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);
}
/**
* 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 );
}
/**
* Counts the number of items 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.
* @return the number of found in {@code iterator}.
*/
public static int count( Iterator iterator )
{
int result = 0;
while ( iterator.hasNext() )
{
iterator.next();
result++;
}
return result;
}
/**
* 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.
* @return the number of found in {@code iterator}.
*/
public static int count( Iterable iterable )
{
return count( iterable.iterator() );
}
/**
* 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 )
{
List list = new ArrayList();
addToCollection( iterable, list );
return list;
}
/**
* 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() );
}
/**
* Creates a {@link Set} from an array of items.
*
* @param items the items to add to the set.
* @return the {@link Set} containing the items.
*/
public static Set asSet( T... items )
{
return new HashSet( asList( items ) );
}
/**
* Creates an {@link Iterable} for iterating over the lines of a text file.
* @param file the file to get the lines for.
* @return an {@link Iterable} for iterating over the lines of a text file.
*/
public static ClosableIterable asIterable( final File file )
{
return new ClosableIterable()
{
private ClosableIterator mostRecentIterator;
@Override
public Iterator iterator()
{
try
{
if ( mostRecentIterator != null ) mostRecentIterator.close();
mostRecentIterator = asIterator( file );
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.
* @return an {@link Iterator} for iterating over the lines of a text file.
*/
public static ClosableIterator asIterator( File file ) throws IOException
{
return new LinesOfFileIterator( file );
}
public static void streamToFile( Iterable iterable, File file, String encoding ) throws IOException
{
streamToFile( iterable.iterator(), file, encoding );
}
public static void streamToFile( Iterator iterator, File file, String encoding ) throws IOException
{
if ( file.exists() ) throw new IOException( "File '" + file + "' already exists" );
PrintStream out = null;
try
{
out = new PrintStream( file, encoding );
while ( iterator.hasNext() ) out.println( iterator.next().toString() );
}
finally
{
safeClose( out );
}
}
private static void safeClose( Closeable closeable )
{
if ( closeable != null )
{
try
{
closeable.close();
}
catch ( IOException e )
{
// What can we do?
e.printStackTrace();
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy