Как транслировать через диапазон BigIntegers? - PullRequest
3 голосов
/ 10 июля 2019

Здравствуйте, у меня сейчас есть этот кусок кода для поиска факториала, который отлично работает

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> аналогично тому, как я могу объявить IntStream?

IntStream.range(1, myInt);

Ответы [ 2 ]

2 голосов
/ 10 июля 2019

Эквивалент будет

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

, где end - это BigInteger.

Stream.iterate создаст бесконечный поток, начиная с 1 и непрерывно добавляя 1. takeWhile остановит поток, как только условие будет выполнено.

2 голосов
/ 10 июля 2019

Возможно, что-то вроде этого:

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.

...