如何流式传输一系列BigInteger?

时间:2019-07-10 09:37:33

标签: java java-stream biginteger

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

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

所以我的问题是我如何获得类似于声明Stream<BigInteger>的{​​{1}}?

IntStream

2 个答案:

答案 0 :(得分:2)

也许是这样的:

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的数字的阶乘。这样一个数字的阶乘将是巨大的,并且可能需要很长时间才能计算出来。

编辑:这不是一个适当的基准,但是{​​{1}}花了我5秒钟,而factorial(100000)花了8分钟。以这种速率,factorial(1000000)甚至factorial(Long.MAX_VALUE)将花费非常长的时间。因此,我认为没有必要使用factorial(Integer.MAX_VAULE)参数。

答案 1 :(得分:2)

等效为

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

其中endBigInteger

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