Java 8 introduces the new feature Stream, which greatly supports functional programming. To begin with, let’s first take a look at the basic ideas of stream and lambda. The best example to elucidate this would be the generation of Fibonacci numbers. Below is the most ordinary way in Java, with no functional programming at all:
static void printFib(int num){
long first = 0;
long second = 1;
long fib = 0;
for (int c = 2; c <= num; c++){
fib = first + second;
first = second;
second = fib;
}
System.out.println("The " + num + "th Fibonacci number is " + fib);
}
By using the idea of lazy evaluation, we calculate the next number when we need it. The method looks like this:
public static LazyList nextFib(long p1, long p2) {
return new LazyList<>(p1, ()->nextFib(p2, p1+p2));
}
And the method call would be:
LazyList fibonacciList = nextFib(0, 1);
fibonacciList.stream().limit(10).forEach(System.out::println);
Where 10 is the length of the sequence you want to generate.
We can apply this idea to generating all kinds of interesting sequences, but a trickier play would be using stream, lambda and lazy evaluation to do some calculations. One of these applications is calculating the square root of a number. Say I want to find the square root of 7. First let’s start with 1 and 7, where both squares are not 7. So we take the midpoint of 1 and 7, which is 4. Since 4 square is greater than 7, we then start with 1 and 4 and repeat all operations again. The number of such iterations is user’s choice. A simple algorithm, right? It actually reaches the limit of floating number pretty fast.
public static LazyList squareRoot(double low, double high, double num) {
double mid = (low + high)/2;
return new LazyList<>(low,
mid*mid > num?()->squareRoot(low,mid,num):()->squareRoot(mid,high,num));
}
squareRoot(1,5,3.14).stream().limit(15).forEach(System.out::println);
This prints out all tries during the iterations.
The result of calculating the square root of 90 with 15 iterations, with initial tries 1 and 10:
0
1
1
2
3
5
8
13
21
34
1.0
5.5
7.75
8.875
9.4375
9.4375
9.4375
9.4375
9.47265625
9.47265625
9.4814453125
9.48583984375
9.48583984375
9.48583984375
9.48638916015625
9.486663818359375
9.486801147460938
9.486801147460938
9.486801147460938
9.486818313598633
9.48682689666748
9.486831188201904
9.486831188201904
9.48683226108551
9.486832797527313
Obviously it leads to an accurate answer.