Fibonacci Streaming in Java


The challenge

You’re going to provide a needy programmer a utility method that generates an infinite sized, sequential IntStream which contains all the numbers in a fibonacci sequence.

A fibonacci sequence starts with two 1s. Every element afterwards is the sum of the two previous elements. See:

1, 1, 2, 3, 5, 8, 13, ..., 89, 144, 233, 377, ...

The solution in Java code

Option 1:

import java.util.function.IntSupplier;
import java.util.stream.IntStream;

public class Utility {

    public static IntStream generateFibonacciSequence() {
        return IntStream.generate(new IntSupplier() {
            int a = 0;
            int b = 1;

            @Override
            public int getAsInt() {
                int x = a + b;
                a = b;
                b = x;
                return a;
            }
        });
    }
}

Option 2:

import java.util.stream.Stream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

public class Utility {

    public static IntStream generateFibonacciSequence() {
        return Stream.iterate(new Integer[]{1, 1}, p -> new Integer[]{p[1], p[0] + p[1]})
                .mapToInt(integers -> integers[0]);
    }

}

Option 3:

import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.concurrent.atomic.AtomicInteger;

public class Utility {

    public static IntStream generateFibonacciSequence() {
        AtomicInteger fibonacci = new AtomicInteger(1);
        return IntStream.iterate(1, x -> fibonacci.getAndAdd(x));
    }

}

Test cases to validate our solution

import org.junit.Test;
import java.util.PrimitiveIterator;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.fail;

public class TestSuite {

    @Test
    public void testThatTheFirstTwentyElementsAreCorrect() {
        assertArrayEquals("The first twenty elements are incorrect!",
          new int[] {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765},
          Utility.generateFibonacciSequence().limit(20).toArray());
    }

    @Test(timeout = 30)
    public void testRecursivePropertyInStreamByRandomLeaps() {
        for (int i = 0; i < 3; i++) { // Repeat three times
            final PrimitiveIterator.OfInt iterator =
                Utility.generateFibonacciSequence()
                    .skip((int) (Math.random() * 900)) // Begin leap
                    .limit(20) // End leap
                    .iterator();
            int previous = iterator.nextInt(),
                current = iterator.nextInt();
            while (iterator.hasNext()) {
                final int next = iterator.next();
                if (next != previous + current)
                    fail(String.format("Elements %s, %s are followed by %s!", previous, current, next));
                previous = current;
                current = next;
            }
        }
    }

}