Вопрос проверяет умение использовать Stream API для агрегации элементов коллекции, что важно для функционального стиля программирования в Java.
Stream API в Java предоставляет мощный набор операций для обработки последовательностей данных в функциональном стиле. Одной из ключевых операций является reduce, которая используется для свертки (агрегации) элементов потока в одно значение, например, для нахождения суммы, произведения, максимума или конкатенации строк.
Метод reduce принимает два аргумента:
BinaryOperator<T>, которая принимает текущее значение аккумулятора и следующий элемент потока, возвращая новое значение аккумулятора.Поток последовательно обрабатывает элементы, применяя функцию аккумулятора. Например, для списка [2, 3, 4] операция reduce(1, (a, b) -> a * b) выполнит вычисления: 1 * 2 = 2, 2 * 3 = 6, 6 * 4 = 24, и вернет 24.
import java.util.List;
public class StreamMultiply {
public static void main(String[] args) {
List<Integer> numbers = List.of(2, 3, 4);
// Умножение с reduce
int product = numbers.stream()
.reduce(1, (a, b) -> a * b);
System.out.println("Произведение: " + product); // Вывод: 24
// Альтернатива с методом-ссылкой
int product2 = numbers.stream()
.reduce(1, Math::multiplyExact);
System.out.println("Произведение (с Math::multiplyExact): " + product2);
}
}Операция reduce полезна в различных сценариях:
Важно помнить, что для пустого потока reduce с идентичностью вернет это начальное значение (например, 1), что обеспечивает безопасность. Без идентичности метод вернет Optional, который нужно обрабатывать отдельно.
Вывод: Используйте reduce в Stream API, когда нужно заменить императивные циклы на декларативную агрегацию данных, особенно в контексте функционального программирования для повышения читаемости и поддержки кода.