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

src-lib.atlas.iterator.Iter Maven / Gradle / Ivy

There is a newer version: 0.8.10
Show newest version
/*
 * (c) Copyright 2007, 2008, 2009 Hewlett-Packard Development Company, LP
 * All rights reserved.
 * [See end of file]
 */

package atlas.iterator;


import java.util.*;

import atlas.lib.Action;
import atlas.lib.ActionKeyValue;


public class Iter implements Iterable, Iterator
{
    // First part : the static function library.
    // Often with both Iterator and Iterable
    
    public static  Iterator singleton(T item)
    { return new SingletonIterator(item) ; }

    public static  Iterator nullIterator()
    { return new NullIterator() ; }
    
    public static  Set toSet(Iterable stream) { return toSet(stream.iterator()); }

    public static  Set toSet(Iterator stream)
    {
        Accumulate> action = new Accumulate>()
        {
            private Set acc = null ;
            public void accumulate(T item)  { acc.add(item) ; }
            public Set get()             { return acc ; }
            public void start()             { acc = new HashSet() ; }
            public void finish()            {}
        } ;
        return reduce(stream, action) ;
    }

    public static  List toList(Iterable stream)
    { return toList(stream.iterator()) ; }

    public static  List toList(Iterator stream)
    {
        Accumulate> action = new Accumulate>()
        {
            private List acc = null ;
            public void accumulate(T item)  { acc.add(item) ; }
            public List get()            { return acc ; }
            public void start()             { acc = new ArrayList() ; }
            public void finish()            {}
        } ;
        return reduce(stream, action) ;
    }

    // Note fold-left and fold-right
    // http://en.wikipedia.org/wiki/Fold_%28higher-order_function%29
    // This reduce is fold-right (take first element, apply to rest of list)
    // which copes with infinite lists.
    // Fold-left starts combining from the list tail.
    
    public static  R reduce(Iterable stream, Accumulate aggregator)
    { return reduce(stream.iterator(), aggregator) ; }

    public static  R reduce(Iterator stream, Accumulate aggregator)
    {
        aggregator.start();
        for ( ; stream.hasNext() ; )
        {
            T item = stream.next(); 
            aggregator.accumulate(item) ;
        }
        aggregator.finish();
        return aggregator.get();
    }

    // map without the results - do immediately.
    
    public static  void apply(Iterable stream, Action action)
    { apply(stream.iterator(), action) ; }

    public static  void apply(Iterator stream, Action action)
    {
        for ( ; stream.hasNext() ; )
        {
            T item = stream.next(); 
            action.apply(item) ;
        }
    }
    
    // -- Map specific apply.  No results - do immediately.
    
    public static  void apply(Map map, ActionKeyValue action)
    {
        for ( Map.Entry entry : map.entrySet() )
            action.apply(entry.getKey(), entry.getValue()) ;
    }
    
    // ---- Filter
    
    public static  Iterator filter(Iterable stream, Filter filter)
    { return filter(stream.iterator(), filter) ; }

    public static  Iterator filter(final Iterator stream, final Filter filter)
    {
        final Iterator iter = new Iterator(){
            
            boolean finished = false ; 
            T slot ;
            
            public boolean hasNext()
            {
                if ( finished )
                    return false ; 
                while ( slot == null )
                {
                    if ( ! stream.hasNext() )
                    { 
                        finished = true ;
                        break ;
                    }
                    T nextItem = stream.next() ;
                    if ( filter.accept(nextItem) )
                    { 
                        slot = nextItem ;
                        break ;
                    }
                }
                return slot != null ;
            }
    
            public T next()
            {
                if ( hasNext() )
                {
                    T returnValue = slot ;
                    slot = null ;
                    return returnValue ;
                }
                throw new NoSuchElementException("filter.next") ;
            }
    
            public void remove() { throw new UnsupportedOperationException("filter.remove") ; }
        } ;
        
        return iter ;
    }
    
    
    private static class InvertedFilter implements Filter
    {
        public static  Filter invert(Filter filter) { return new InvertedFilter(filter) ; }
        private Filter baseFilter ;
        private InvertedFilter(Filter baseFilter) { this.baseFilter = baseFilter ; }
        
        public boolean accept(T item)
        {
            return ! baseFilter.accept(item) ;
        }
    }
    
    public static  Iterator notFilter(Iterable stream,
                                         Filter filter)
    { return notFilter(stream.iterator(), filter) ; }
    
    public static  Iterator notFilter(final Iterator stream, final Filter filter)
    {
        Filter flippedFilter = InvertedFilter.invert(filter) ;
        return filter(stream, flippedFilter) ;
    }
    
    // Filter-related
    
    /** Return true if every element of stream passes the filter (reads the stream) */
    public static  boolean every(Iterable stream, Filter filter)
    { 
        for ( T item : stream )
            if ( ! filter.accept(item) ) 
                return false ;
        return true ;
    }

    /** Return true if every element of stream passes the filter (reads the stream until the first element not passing the filter) */
    public static  boolean every(Iterator stream, Filter filter)
    { 
        for ( ; stream.hasNext() ; )
        {
            T item = stream.next();
            if ( ! filter.accept(item) ) 
                return false ;
        }
        return true ;
    }

    /** Return true if every element of stream passes the filter (reads the stream) */
    public static  boolean some(Iterable stream, Filter filter)
    { 
        for ( T item : stream )
            if ( filter.accept(item) ) 
                return true ;
        return false ;
    }

    /** Return true if one or more elements of stream passes the filter (reads the stream to first element passing the filter) */
    public static  boolean some(Iterator stream, Filter filter)
    { 
        for ( ; stream.hasNext() ; )
        {
            T item = stream.next();
            if ( filter.accept(item) ) 
                return true ;
        }
        return false ;
    }

    
    // ---- Map

    public static  Iterator map(Iterable stream, Transform converter)
    { return map(stream.iterator(), converter) ; }

    public static  Iterator map(final Iterator stream, final Transform converter)
    {
        final Iterator iter = new Iterator(){
            public boolean hasNext()
            {
                return stream.hasNext() ;
            }
    
            public R next()
            {
                return converter.convert(stream.next()) ;
            }
    
            public void remove() { throw new UnsupportedOperationException("map.remove") ; }
        } ;
        return iter ;
    }
    
    /** Apply an action to everything in stream, yielding a stream of the same items */ 
    public static  Iterator operate(Iterable stream, Action converter)
    { return operate(stream.iterator(), converter) ; }

    /** Apply an action to everything in stream, yielding a stream of the same items */ 
    public static  Iterator operate(final Iterator stream, 
                                          final Action action)
    {
        final Iterator iter = new Iterator(){
            public boolean hasNext()
            {
                return stream.hasNext() ;
            }
    
            public T next()
            {
                T t = stream.next() ;
                action.apply(t) ;
                return t ;
            }
    
            public void remove() { throw new UnsupportedOperationException("operate.remove") ; }
        } ;
        return iter ;
    }
    
  

    
    public static  Iterator append(Iterable iter1, Iterable iter2)
    {
        return Iterator2.create(iterator(iter1), iterator(iter2));
    }

    // Could try for  on each arg.
    public static  Iterator append(Iterator iter1, Iterator iter2)
    { return Iterator2.create(iter1, iter2); }

    private static  Iterator iterator(Iterable iter) { return (iter==null) ? null : iter.iterator() ; }
    
    public static  Iterator distinct(Iterable iter)
    {
        return distinct(iter.iterator()) ;
    }

    public static  Iterator distinct(Iterator iter)
    {
        return filter(iter, new FilterUnique()) ;
    }
    
    public static  Iterator removeNulls(Iterable iter)
    {
        return filter(iter, new FilterOutNulls()) ;
    }
    
    public static  Iterator removeNulls(Iterator iter)
    {
        return filter(iter, new FilterOutNulls()) ;
    }
    
    @SuppressWarnings("unchecked")
    public static  Iterator convert(Iterator iterator) { return (Iterator)iterator ; }
    
    /** Count the iterable - many iterable objects have a .size() operation which shoudl be used in preference to this explicit counting operation  */ 
    public static  long count(Iterable iterator)
    {
        ActionCount action = new ActionCount() ;
        Iter.apply(iterator, action) ;
        return action.getCount() ;
    }

    /** Count the iterator (this is destructive on the iterator) */ 
    public static  long count(Iterator iterator)
    {
        ActionCount action = new ActionCount() ;
        Iter.apply(iterator, action) ;
        return action.getCount() ;
    }

    // ---- String related helpers
    
    public static  String asString(Iterable stream)
    { return asString(stream, new AccString()) ; }

    public static  String asString(Iterator stream)
    { return asString(stream, new AccString()) ; }

    public static  String asString(Iter stream)
    { return asString(stream, new AccString()) ; }

    public static  String asString(Iterable stream, String sep)
    { return asString(stream, new AccString(sep)) ; }

    public static  String asString(Iterator stream, String sep)
    { return asString(stream, new AccString(sep)) ; }

    public static  String asString(Iter stream, String sep)
    { return asString(stream.iterator(), new AccString(sep)) ; }

    public static  String asString(Iterable stream, AccString formatter)
    { return reduce(stream, formatter) ; }

    public static  String asString(Iterator stream, AccString formatter)
    { return reduce(stream, formatter) ; }

    public static  String asString(Iter stream, AccString formatter)
    { return reduce(stream.iterator(), formatter) ; }

    // ----
    
    public static  void close(Iterator iter)
    {
        if ( iter instanceof ClosableIterator )
            ((ClosableIterator)iter).close() ;
    }

    public static  Iterator debug(Iterator stream)
    { 
        Transform x = new Transform()
        {
            //@Override
            public T convert(T item)
            { 
                System.out.println(item) ;
                return item ;
            }
        } ;
        return map(stream, x) ;
    }
    //----
    // Iter class part
    // And ....
    // Could merge in concatenated iterators - if used a lot there is reducable cost.
    // Just putting in a slot is free (?) because objects of one or two slots have
    // the same memory allocation.
    // And .. be an iterator framework for extension
    
    // Or dynamically with a subclass and a static constructor
    // List concatenated = null ; 
    
    public static  Iter iter(Iter iter)
    { return iter ; }
    
    public static  Iter iter(Collection collection)
    {
        return Iter.iter(collection.iterator()) ;
    }
    
    public static  Iter iter(Iterator iterator)
    { 
        if ( iterator instanceof Iter )
            return (Iter)iterator ;
        return new Iter(iterator) ;
    }
    
    public static  Iter iter(Iterable iterable)
    { 
        if ( iterable instanceof Iter )
            return (Iter)iterable ;
        return new Iter(iterable.iterator()) ;
    }
    
    public static  Iter concat(Iter iter1, Iteriter2)
    { 
        if ( iter1 == null )
            return iter2 ;
        if ( iter2 == null )
            return iter1 ;
        return iter1.append(iter2) ;
    }

    // ------------------------------------------------------
    // The class.
    
    private Iterator iterator ;
    private Iter(Iterator iterator) { this.iterator = iterator ; }
    
    public Set toSet()
    {
        return toSet(iterator) ;
    }

    public List toList()
    {
        return toList(iterator) ;
    }

    public Iter filter(Filter filter)
    {
        return iter(filter(iterator, filter)) ;
    }

    public boolean every(Filter filter)
    {
        return every(iterator, filter) ;
    }
    
    public boolean some(Filter filter)
    {
        return some(iterator, filter) ;
    }
    
    public Iter removeNulls()
    {
        return filter(new FilterOutNulls()) ;
    }

    public  Iter map(Transform converter)
    {
        return iter(map(iterator, converter)) ;
    }
    
    /** Apply an action to everything in the stream, yielding a stream of the same items */ 
    public Iter operate(Action action)
    {
        return iter(operate(iterator, action)) ;
    }

    public  R reduce(Accumulate aggregator)
    {
        return reduce(iterator, aggregator) ;
    }

    public void apply(Action action)
    {
        apply(iterator, action) ;
    }

    public Iter append(Iterator iter)
    {
        return new Iter(Iterator2.create(iterator, iter)) ;
    }

    /** Count the iterator (this is destructive on the iterator) */ 
    public long count()
    {
        ActionCount action = new ActionCount() ;
        apply(action) ;
        return action.getCount() ;
    }
    
    public String asString() { return asString(iterator) ; }
    public String asString(String sep) { return asString(iterator, sep) ; }
    
    public Iter distinct()
    {
        return new Iter(distinct(iterator())) ;
    }

    // ---- Iterable
    public Iterator  iterator() { return iterator ; }
    
    // ---- Iterator
    
    //----
    // Could merge in concatenated iterators - if used a lot there is reducable cost.
    // Just putting in a slot is free (?) because objects of one or two slots have
    // the same memory allocation.
    // And .. be an iterator framework for extension
    
    public boolean hasNext()    { return iterator.hasNext() ; }

    public T next()             { return iterator.next() ; }

    public void remove()        { iterator.remove() ; }

    //----
    // Iter class part
    // And ....
    // Could merge in concatenated iterators - if used a lot there is reducable cost.
    // Just putting in a slot is free (?) because objects of one or two slots have
    // the same memory allocation.
    // And .. be an iterator framework for extension
    
    // Or dynamically with a subclass and a static constructor
    // List concatenated = null ; 
    
    public static  Iter singletonIter(T item)
    { return new Iter(new SingletonIterator(item)) ; }

    public static  Iter nullIter()
    { return new Iter(new NullIterator()) ; }
}

/*
 * (c) Copyright 2007, 2008, 2009 Hewlett-Packard Development Company, LP
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */




© 2015 - 2025 Weber Informatics LLC | Privacy Policy