<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: iterator code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Wed, 08 Oct 2008 00:19:27 GMT</pubDate>
    <description>DZone Snippets: iterator code</description>
    <item>
      <title>Flattening iterator</title>
      <link>http://snippets.dzone.com/posts/show/3523</link>
      <description>A trivial utility class for iterating through a collection of objects in a 'flat' manner, descending into any collections (in this case defined as iterators, iterables or arrays, rather than elements of the Collection interface ) it finds and iterating through their elements. This preserves order, so {a, b, {c, d, {e}}} will be iterated through as a, b, c, d, e.&lt;br /&gt;&lt;br /&gt;It's not very complicated, but the implementation amused me so I thought I'd share it.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;package playground.library.functional.iterator;&lt;br /&gt;&lt;br /&gt;import java.lang.reflect.Array;&lt;br /&gt;import java.util.Arrays;&lt;br /&gt;import java.util.Iterator;&lt;br /&gt;import java.util.NoSuchElementException;&lt;br /&gt;import java.util.Stack;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * An iterator that 'flattens out' collections, iterators, arrays, etc. &lt;br /&gt; *&lt;br /&gt; * That is it will iterate out their contents in order, descending into any &lt;br /&gt; * iterators, iterables or arrays provided to it.&lt;br /&gt; *&lt;br /&gt; * An example (not valid Java for brevity - some type declarations are ommitted):&lt;br /&gt; *&lt;br /&gt; * new FlattingIterator({1, 2, 3}, {{1, 2}, {3}}, new ArrayList({1, 2, 3}))&lt;br /&gt; *&lt;br /&gt; * Will iterate through the sequence 1, 2, 3, 1, 2, 3, 1, 2, 3.&lt;br /&gt; *&lt;br /&gt; * Note that this implements a non-generic version of the Iterator interface so&lt;br /&gt; * may be cast appropriately - it's very hard to give this class an appropriate &lt;br /&gt; * generic type.&lt;br /&gt; *&lt;br /&gt; * @author david&lt;br /&gt; */&lt;br /&gt;public class FlatteningIterator implements Iterator&lt;br /&gt;{&lt;br /&gt;    // Marker object. This is never exposed outside this class, so can be guaranteed&lt;br /&gt;    // to be != anything else. We use it to indicate an absense of any other object.&lt;br /&gt;    private final Object blank = new Object();&lt;br /&gt;    &lt;br /&gt;    /* This stack stores all the iterators found so far. The head of the stack is&lt;br /&gt;     * the iterator which we are currently progressing through */&lt;br /&gt;    private final Stack&lt;Iterator&lt;?&gt;&gt; iterators = new Stack&lt;Iterator&lt;?&gt;&gt;();&lt;br /&gt;    &lt;br /&gt;    // Storage field for the next element to be returned. blank when the next element&lt;br /&gt;    // is currently unknown.&lt;br /&gt;    private Object next = blank;&lt;br /&gt;        &lt;br /&gt;    public FlatteningIterator(Object... objects){&lt;br /&gt;        this.iterators.push(Arrays.asList(objects).iterator());}&lt;br /&gt;    &lt;br /&gt;    public void remove(){&lt;br /&gt;        /* Not implemented */}&lt;br /&gt;    &lt;br /&gt;    private void moveToNext(){&lt;br /&gt;        if ((next == blank) &amp;&amp; !this.iterators.empty() ) {&lt;br /&gt;            if (!iterators.peek().hasNext()){&lt;br /&gt;                iterators.pop();&lt;br /&gt;                moveToNext();}&lt;br /&gt;                else{&lt;br /&gt;                    final Object next = iterators.peek().next();&lt;br /&gt;                    if (next instanceof Iterator){&lt;br /&gt;                      iterators.push((Iterator&lt;?&gt;)next);&lt;br /&gt;                      moveToNext();}&lt;br /&gt;                    else if (next instanceof Iterable){&lt;br /&gt;                       iterators.push(((Iterable)next).iterator());&lt;br /&gt;                       moveToNext();}&lt;br /&gt;                    else if (next instanceof Array){&lt;br /&gt;                        iterators.push(Arrays.asList((Array)next).iterator());&lt;br /&gt;                        moveToNext();}&lt;br /&gt;                    else this.next = next;}}}&lt;br /&gt;    &lt;br /&gt;    /**&lt;br /&gt;     * Returns the next element in our iteration, throwing a NoSuchElementException&lt;br /&gt;     * if none is found. &lt;br /&gt;     */&lt;br /&gt;    public Object next() {&lt;br /&gt;        moveToNext();&lt;br /&gt;        &lt;br /&gt;        if (this.next == blank) throw new NoSuchElementException();&lt;br /&gt;        else{&lt;br /&gt;            Object next = this.next;&lt;br /&gt;            this.next = blank;&lt;br /&gt;            return next;&lt;br /&gt;        }}&lt;br /&gt;    &lt;br /&gt;    /**&lt;br /&gt;     * Returns if there are any objects left to iterate over. This method &lt;br /&gt;     * can change the internal state of the object when it is called, but repeated&lt;br /&gt;     * calls to it will not have any additional side effects.&lt;br /&gt;     */&lt;br /&gt;    public boolean hasNext(){&lt;br /&gt;        moveToNext();&lt;br /&gt;        return (this.next != blank);}    &lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Wed, 14 Feb 2007 19:02:51 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3523</guid>
      <author>DRMacIver (David R. MacIver)</author>
    </item>
  </channel>
</rss>
