Java функциональное программирование, случайный int, поток, математика, абс не работает - PullRequest
2 голосов
/ 21 апреля 2020

У меня есть следующий код:

import java.util.Random;
import java.util.stream.Stream;

public class StreamIntReduce
{
    public static void main(String[] args)
    {
        Stream.generate(() -> new Random().nextInt())
                .limit(100000)
                .map(x -> Math.abs(x))
                .reduce((a,b) -> {
                    System.out.println(a);
                    System.out.println(b);
                    return a + b;
                })
                .ifPresent(System.out::println);
    }
}

Я использую .map(x -> Math.abs(x)) для преобразования отрицательных чисел в положительные. Почему мои выходные данные System.out.println(a); и System.out.println(b); все еще содержат отрицательные числа?

-1293102468
2036920025
743817557
939157978
1682975535
1444066960
-1167924801
1361593362
193668561
1764534904
1958203465
739693193
-1597070638

1 Ответ

2 голосов
/ 21 апреля 2020

Здесь пара замечаний:

Метод .nextInt() возвращает как положительные, так и отрицательные числа. Если вам нужны только положительные значения, вызовите перегруженный метод .nextInt(bound) с положительной границей. Таким образом, вы можете отбросить отображение x -> Math.abs(x).


Тип Integer ограничен Java. Он имеет строго определенные верхнюю и нижнюю границы:

public static final int MIN_VALUE = -2147483648;
public static final int MAX_VALUE = 2147483647;

Когда вы добавляете два числа и сумма больше, чем MAX_VALUE, тогда биты overflow и бит знака изменяются. Таким образом, суммирование двух больших Integer чисел может привести к отрицательному результату в Java (и не только).


Если вы все еще хотите суммировать такие числа, вы можете использовать BigInteger вместо Integer.

Модифицированный код выглядит так:

 Stream.generate(() -> new Random().nextInt(Integer.MAX_VALUE))
       .limit(100000)
       .map(BigInteger::valueOf)
       .reduce((a, b) -> {
                  System.out.println(a);
                  System.out.println(b);
                  return a.add(b);
       })
       .ifPresent(System.out::println);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...