Что на самом деле уменьшает поток Java, если только один из аргументов BinaryOperator суммируется с самим собой? - PullRequest
4 голосов
/ 11 марта 2019

Посмотрите на код ниже: здесь в бинарном операторе мы имеем Reduce ((x, y) -> x + x). Почему он фактически рассчитан на Необязательный [512]? У меня нет объяснения.

System.out.println((Stream.generate(()->1d).limit(10).
            peek((doubleValue)->{
                System.out.println("Call the first peek: "+doubleValue);
            }).
            reduce((x,y)->x+x)));

А вот и вывод: просто чтобы прояснить для вас, я показываю, что отдельные x равны 1,0 в разделе просмотра.

Call the first peek: 1.0
Call the first peek: 1.0
Call the first peek: 1.0
Call the first peek: 1.0
Call the first peek: 1.0
Call the first peek: 1.0
Call the first peek: 1.0
Call the first peek: 1.0
Call the first peek: 1.0
Call the first peek: 1.0
Optional[512.0]

Итак, вопрос, что управляет сокращением до работы, пока не будет получен Optional [512]?

Ответы [ 3 ]

6 голосов
/ 11 марта 2019

Поскольку у вас есть 10 аргументов, но операций - 9. 2 ^ 9 = 512

2 голосов
/ 11 марта 2019

Технически, Stream Reduction не предлагает делать что-либо непротиворечивое, когда вы делаете это.

Гарантии предоставляются только с ассоциативными сокращающими операциями, а ваши нет (он учитывает первый операнд и игнорирует второй.)

При тестировании вашего кода вы наблюдаете результаты.

Эти результаты ни в коем случае не удивляют, когда вы пытаетесь сделать обоснованное предположение о том, как сокращение реализовано в непараллельных потоках. Однако эти результаты никоим образом не гарантируются документацией Stream, поскольку вы не соблюдали требования.

Например, результат мог быть 1 или 2. Хотя это немного озадачивает, это все же имеет смысл, и вы тот, кто не соответствует требованиям.

1 голос
/ 11 марта 2019

Посмотрим, что здесь происходит:

    System.out.println((Stream.generate(()->1d).limit(10).
            reduce((x,y)-> {
                double ret = x+x;
                System.out.println(ret);
                return ret;
            })));

Выход

2.0
4.0
8.0
16.0
32.0
64.0
128.0
256.0
512.0
Optional[512.0]

Поскольку в вашем потоке 10 аргументов, предоставленных , уменьшают со начальным значением по умолчанию 0.

Поскольку вы используете (x, y) -> x+x, и вы фактически удваиваете результат более чем в 9 раз, как result <- result + result после первого, где result <- 0 + 1, как упомянуто @ZhenyaM: 2^9 = 512

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...