Last active
June 25, 2019 09:01
-
-
Save rakeshopensource/93e6ec6b02560887a6088110cc5df877 to your computer and use it in GitHub Desktop.
Factorial with Java8 Stream API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.math.BigInteger; | |
import java.util.stream.Stream; | |
@FunctionalInterface | |
interface Call<T> { | |
Call<T> apply(); | |
default boolean isComplete() { | |
return false; | |
} | |
default T result() { | |
throw new Error("not implemented"); | |
} | |
default T invoke() { | |
return Stream.iterate(this, Call::apply) | |
.filter(Call::isComplete) | |
.findFirst() | |
.get() | |
.result(); | |
} | |
} | |
class Calls { | |
public static BigInteger decrement(final BigInteger number) { | |
return number.subtract(BigInteger.ONE); | |
} | |
public static BigInteger multiply( | |
final BigInteger first, final BigInteger second) { | |
return first.multiply(second); | |
} | |
public static BigInteger fact(BigInteger number) { | |
return factorial(BigInteger.ONE, number).invoke(); | |
} | |
public static Call<BigInteger> factorial(final BigInteger factorial, final BigInteger number) { | |
if (number.equals(BigInteger.ONE)) | |
return done(factorial); | |
else | |
return call(() -> factorial(multiply(factorial, number), decrement(number))); | |
} | |
public static <T> Call<T> call(final Call<T> nextCall) { | |
return nextCall; | |
} | |
public static <T> Call<T> done(final T value) { | |
return new Call<T>() { | |
@Override | |
public boolean isComplete() { | |
return true; | |
} | |
@Override | |
public T result() { | |
return value; | |
} | |
@Override | |
public Call<T> apply() { | |
throw new Error("not implemented"); | |
} | |
}; | |
} | |
} | |
public class Factorial { | |
public static void main(String[] args) { | |
System.out.println("Factorial : " + Calls.fact(new BigInteger("100"))); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Initial commit