如何流式传输一系列 BigIntegers?

How to stream over a range of BigIntegers?

你好,我目前有这段代码可以很好地找到阶乘

public static BigInteger factorial(BigInteger n) {
    BigInteger sum = BigInteger.ONE;
    for (BigInteger i = BigInteger.ONE; i.compareTo(n) <= 0; i = i.add(BigInteger.ONE)) {
        sum = sum.multiply(i);
    }
    return sum;
}

我想实现的是把它转换成一个Stream<BigInteger>然后这样写

public static BigInteger factorial(BigInteger n) {
    return getBigIntegerStream(n).reduce(BigInteger.ONE, BigInteger::multiply);
}

所以我的问题是如何获得类似于声明 IntStreamStream<BigInteger>?

IntStream.range(1, myInt);

也许是这样的:

public static BigInteger factorial(BigInteger n) {
    return Stream.iterate (BigInteger.ONE, i -> i.add(BigInteger.ONE)).limit(Integer.parseInt(n.toString())).reduce(BigInteger.ONE, BigInteger::multiply);
}

编辑:我忘了限制流。现已修复。

当然,接受一个int(或long)作为参数会更简单:

public static BigInteger factorial(int n) {
    return Stream.iterate (BigInteger.ONE, i -> i.add(BigInteger.ONE)).limit(n).reduce(BigInteger.ONE, BigInteger::multiply);
}

您甚至不太可能需要计算大于 Integer.MAX_VALUE 的数字的阶乘。这样一个数字的阶乘会很大,可能需要很长时间才能计算出来。

编辑:不是一个合适的基准,但是 factorial(100000) 花了我 5 秒,factorial(1000000) 花了 8 分钟。按照这个速度,factorial(Long.MAX_VALUE) 甚至 factorial(Integer.MAX_VAULE) 将需要非常非常长的时间。因此,我不认为需要 BigInteger 参数有什么意义。

等同于

Stream.iterate(BigInteger.ONE, i -> i.add(BigInteger.ONE))
    .takeWhile(i -> i.compareTo(end) < 0)

其中 endBigInteger

Stream.iterate 将创建一个无限流,从 1 开始并不断添加 1。一旦满足条件,takeWhile 将停止流。

您可以尝试这样的操作:

public static BigInteger factorial(int n) 
{ 
  return IntStream.rangeClosed(1,n)
                  .mapToObj(BigInteger::valueOf)
                  .reduce(BigInteger::multiply)
}