I am relatively new in Java 8 and lambda expressions as well as Stream
, i can calculate factorial using for
loop or recursion. But is there a way t
To get a stream of all infinite factorials, you can do:
class Pair{
final int num;
final int value;
Pair(int num, int value) {
this.num = num;
this.value = value;
}
}
Stream<Pair> allFactorials = Stream.iterate(new Pair(1,1),
x -> new Pair(x.num+1, x.value * (x.num+1)));
allFactorials
is a stream of factorials of number starting from 1 to ..... To get factorials of 1 to 10:
allFactorials.limit(10).forEach(x -> System.out.print(x.value+", "));
It prints: 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800,
Now say you only wish to have a factorial of a particular number then do:
allFactorials.limit(number).reduce((previous, current) -> current).get()
The best part is that you dont recompute again for new numbers but build on history.
You can use IntStream::reduce for this job,
int number = 5;
IntStream.rangeClosed(2, number).reduce(1, (x, y) -> x * y)
I think we can change the main condition to: 1,vv-1,st with the function reduce. Maybe we can filter before we did the main rule
With LongStream.range() you can calculate factorial for number less 20. If you need calculate for larger number create stream with BigInteger:
public BigInteger factorial(int number) {
if (number < 20) {
return BigInteger.valueOf(
LongStream.range(1, number + 1).reduce((previous, current) -> previous * current).getAsLong()
);
} else {
BigInteger result = factorial(19);
return result.multiply(Stream.iterate(BigInteger.valueOf(20), i -> i.add(BigInteger.ONE)).limit(number - 19)
.reduce((previous, current) -> previous.multiply(current)).get()
);
}
}