Yield 4 Java

Generator.java – Extending Java with Yield

The yield statement in Ruby, Python and C# makes it very convenient to write complex iterators. As this has been missing in Java so far, here is a class that you can subclass to create generators.

Generator implements an iterator that yields its values one at a time. Subclasses must define a method called #run() and may call yield(T) to return values one at a time.

The generator ends when it reaches a return statement or the end of the method. On the other hand, an generator may run forever and thus yield an infinite sequence (see Example 1 for an example).

Please beware that calling #hasNext() on the generator (and thus any use in a for-each loop) provokes a lookahead of one value. Therefore you cannot repeatedly yield the same object, but rather, you must clone the value on each yield statement (see Example 3 for an example).

NB: this class makes use of Threads, you might want to double-check its source code before using it in a multi-threaded application.

Example 1: Yields an infinite sequence of fibonacci numbers.

    Generator<Integer> fibonacci = new Generator<Integer>() {
        @Override
        public void run() {
            int a = 0, b = 1;
            while (true) {
                a = b + (b = a);
                yield(a); 
            }
        }
    };
    
    for (int x : fibonacci) {
        if (x > 20000) break;
        System.out.println(x);
    }

Example 2: Yields all characters of the string "Hello, Worlds!".

    Generator<char&gt> hello = new Generator<char>() {
        @Override
        public void run() {
            String str = "Hello, Worlds!";
            for (int n = 0; n < str.length; n++) {
                yield(str.atChar(n));
            }
        }
    };
    
    for (char each : hello) {
        System.out.println(each);
    }

Example 3: Yields all perutations of an array.

    public static &lt;T&gt; Generator&lt;T\[]&gt; permute(final T\[] a) {
        return new Generator&lt;T\[]&gt;() {
            &#64;Override
            public void run() {
                permute(a.length - 1);
            }
            private void permute(int n) {
                if (n == 0) yield(a.clone());
                else for (int k = n; k >= 0; k--) {
                    swap(n,k);
                    permute(n - 1);
                    swap(n,k);
                }
            }
            private void swap(int n, int m) {
                T temp = a\[n];
                a\[n] = a\[m];
                a\[m] = temp;
            }
        };
    }

Download

 

 


Contact –

Last changed by admin on 21 April 2009