The Source for Java Technology Collaboration
User: Password:



Rémi Forax

Rémi Forax's Blog

Use foreach to iterate using an Iterator

Posted by forax on September 22, 2006 at 05:09 AM | Comments (4)

When the foreach syntax (for(:)) has been introduced in 1.5, a recurring question was why foreach is not able to iterate using an iterator.

I think i have a trick to do that using the syntax of the closure :

 Iterator<String> scanner=new Scanner(System.in);
 for(String word:() { scanner })
   System.out.println(word);

Why this code works. The foreach statement needs an array or an object that implements java.lang.Iterable. Iterable is an interface that has a single method iterator that returns an iterator thus the closure convertion is applicable.

Rémi


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • You don't need closures to use the foreach with an Iterator. Just create a simple helper class:

    public static final class IteratorIterable<T> implements Iterable<T> {
    private Iteratator<T> iterator;
    public IteratorIterable(Iterator<T> iterator) {
    this.iterator = iterator;
    }
    public Iterator<T> iterator() {
    return iterator;
    }
    }

    and then simply:
    for(String word : new IteratorIterable(scannner)) {
    System.out.println(word);
    }

    Posted by: jessewilson on September 22, 2006 at 09:00 AM

  • hi jessewilson,

    that was cool. I've often wondered(but never enough to get such an easy solution) how to do this.

    thank you,

    BR,
    ~A

    Posted by: anjanb2 on September 22, 2006 at 09:47 AM

  • Your Iterable closure completely breaks the expectations of the interface. To make an Iterable, you would need to do something like:

    for (String word:() { new Scanner(...)}) {
    System.out.println(word);
    }

    Of course, if you had closures, you could just write:

    new Scanner(...).forEachToken(String word) {
    System.out.println(word);
    }

    Posted by: tackline on September 23, 2006 at 01:45 PM

  • An alternative to the IteratorIterable thing is a (probably static) method containing an anonymous class: I'm using [ and ] instead of chevrons because, well, blogs just seem to work better that way.


    public static [T] Iterable[T] iterable(final Iterator[T] iterator)
    {
    return new Iterable[T]()
    {
    public Iterator[T] iterator()
    {
    return iterator;
    }
    };
    }


    However, this Iterable is broken, because it cannot be used reentrantly. It would be better to wrap the original creation of the Scanner in an Iterable.


    public static [T] Iterable[T] newScanner(whateverArgs)
    {
    return new Iterable[T]()
    {
    public Iterator[T] iterator()
    {
    return new Scanner(whateverArgs);
    }
    };
    }


    I'd expect that a closure that just prints whatever you give it could be named, e.g.:


    interface SideEffect[T]
    {
    void run(T input);
    }

    public static final SideEffect[String] sysOutPrintln=new SideEffect[String]()
    {
    public void run(String input)
    {
    System.out.println(input);
    }
    };


    Of course, sysOutPrintln could be changed to be a SideEffect[Object], as there is a println that takes an Object..

    With the closure syntax, perhaps this could be:


    public static final SideEffect[Object] sysOutPrintln=(Object o){System.out.println(o);};


    Cheers.

    Posted by: ricky_clarkson on September 24, 2006 at 04:56 PM



Only logged in users may post comments. Login Here.


Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds