提问者:小点点

使用 Java 8 IntStream 计算阶乘?


我对Java 8和lambda表达式以及< code>Stream比较陌生,我可以使用< code>for循环或递归来计算阶乘。但是有没有办法用< code>IntStream来计算一个数的阶乘呢?即使阶乘在整数范围内,我也没问题。

我在这里阅读了IntStream文档, http://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html 我可以看到很多方法,但不确定我可以使用哪一个来计算阶乘。

例如,有一个< code > range 方法,

range(int startEnclsive, int endExcelsive)返回从startEnclsive(包含)到endExcelsive(独占)的顺序有序IntStream,增量步骤为1。

所以我可以使用它来提供IntStream的数字范围,以便相乘来计算阶乘。

number = 5;
IntStream.range(1, number)

但是如何将这些数字相乘得到阶乘呢?


共3个答案

匿名用户

您可以使用IntStream::reduce来完成这项工作,

int number = 5;
IntStream.rangeClosed(2, number).reduce(1, (x, y) -> x * y)

匿名用户

要获取所有无限阶乘的流,您可以执行以下操作:

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)));

all阶乘是从1到……的数字阶乘流…要获得1到10的阶乘:

allFactorials.limit(10).forEach(x -> System.out.print(x.value+", "));

它打印:1、2、6、24、120、720、5040、40320、362880、3628800,

现在假设你只希望有一个特定数字的阶乘,然后做:

allFactorials.limit(number).reduce((previous, current) -> current).get()

最好的部分是,您不会再次重新计算新数字,而是以历史为基础。

匿名用户

使用 LongStream.range(),您可以计算小于 20 的数字的阶乘。如果您需要计算更大的数字,请使用 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()
        );
    }
}