Разница в Stream.reduce с идентификатором и Stream.reduce().OrElse() — это случай побитового ИЛИ сокращения

#java #java-stream #bitwise-or

#java #java-поток #побитовое или

Вопрос:

Я попробовал два приведенных ниже набора кодов и не увидел никакой разницы в результатах. Я также попытался выполнить реализацию обоих reduce(T identity, BinaryOperator<T> accumulator) и reduce(BinaryOperator<T> accumulator) и не смог заметить никакой разницы, когда функция аккумулятора является побитовой ИЛИ.

 long result1 = myList.stream.reduce((a,b) -> a|b).orElse(0L);
long result2 = myList.stream.reduce(0L,(a,b) -> a|b);
 

Существуют ли какие-либо угловые случаи, которые могли бы привести к другому результату или один из них лучше другого в любом случае?

Ответ №1:

В результатах нет разницы.

Однако я бы разархивировал Stream<Long> элементы в a LongStream , поэтому аккумулятору не нужно будет автоматически блокировать результат (ы).

При этом я бы использовал второй вариант.

 long result = myList.stream()
        .mapToLong(Long::longValue)
        .reduce(0L, (a, b) -> a | b);
 

Комментарии:

1. Итак, если я уверен, что список не будет огромным, окажет ли автобоксинг какое-то влияние?

2. @GauthamM Недостаточно, чтобы заботиться. Напрямую автобоксинг не такой медленный, но он генерирует мусор, поэтому, если вы этого не сделаете, это немного повлияет на прямую производительность, а более частые запуски GC могут повлиять на общую производительность, если процессор ограничен.

3. Я просто попытался сравнить время. mapToLong у меня было намного лучшее время по сравнению с автоматической упаковкой в случае огромных списков. Но это было медленнее в случае меньших списков (хотя разница почти незначительна). Как вы упомянули, учитывая GC, я тоже считаю, что mapToLong это лучший подход. Кроме того, просто для получения дополнительной информации для тех, кому интересно — если список содержит null, трассировки стека исключений немного отличаются с mapToLong инструкцией и без нее.

4. Имейте в виду, что orElse это может принимать любое резервное значение, тогда reduce как требуется значение идентификатора. Только тогда, когда предполагаемый резервный вариант является значением идентификатора, это не имеет никакого значения.