← Назад к вопросам
Приведи пример использования reduce в Stream API
2.0 Middle🔥 211 комментариев
#Stream API и функциональное программирование
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Использование reduce в Stream API
reduce — это терминальная операция в Stream API, которая преобразует поток элементов в одно значение путем аккумуляции. Она особенно полезна для операций типа суммирования, нахождения минимума/максимума, конкатенации строк и других сборок данных.
Три перегрузки метода reduce
// 1. Optional<T> reduce(BinaryOperator<T> accumulator)
Optional<Integer> sum = Arrays.stream(new int[]{1, 2, 3, 4})
.boxed()
.reduce((a, b) -> a + b);
// Результат: Optional[10]
// 2. T reduce(T identity, BinaryOperator<T> accumulator)
int sum = Arrays.stream(new int[]{1, 2, 3, 4})
.boxed()
.reduce(0, (a, b) -> a + b);
// Результат: 10
// 3. <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner)
Integer sum = Arrays.stream(new int[]{1, 2, 3, 4})
.boxed()
.reduce(0,
(accumulator, value) -> accumulator + value, // accumulator
(accumulator1, accumulator2) -> accumulator1 + accumulator2 // combiner
);
// Результат: 10
Практические примеры
Пример 1: Суммирование чисел
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// С начальным значением
int sum = numbers.stream()
.reduce(0, Integer::sum);
System.out.println(sum); // 15
// Без начального значения (возвращает Optional)
Optional<Integer> optionalSum = numbers.stream()
.reduce(Integer::sum);
optionalSum.ifPresent(System.out::println); // 15
Пример 2: Нахождение максимума и минимума
List<Integer> numbers = Arrays.asList(5, 3, 8, 2, 9, 1);
// Максимум
Optional<Integer> max = numbers.stream()
.reduce(Integer::max);
System.out.println(max.orElse(0)); // 9
// Минимум
Optional<Integer> min = numbers.stream()
.reduce(Integer::min);
System.out.println(min.orElse(0)); // 1
Пример 3: Конкатенация строк
List<String> words = Arrays.asList("Hello", "World", "Java");
// С разделителем
String result = words.stream()
.reduce("", (acc, word) -> acc.isEmpty() ? word : acc + " " + word);
System.out.println(result); // Hello World Java
// Альтернатива через String.join
String result2 = String.join(" ", words);
System.out.println(result2); // Hello World Java
Пример 4: Сборка объекта (используется третья перегрузка)
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
List<Person> people = Arrays.asList(
new Person("Alice", 25),
new Person("Bob", 30),
new Person("Charlie", 35)
);
// Подсчет сумму всех возрастов
int totalAge = people.stream()
.reduce(0,
(sum, person) -> sum + person.age,
Integer::sum
);
System.out.println(totalAge); // 90
Пример 5: Аккумуляция в коллекцию
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// Сборка в StringBuilder
String result = numbers.stream()
.reduce(
new StringBuilder(),
(sb, num) -> sb.append(num).append(","),
(sb1, sb2) -> sb1.append(sb2)
)
.toString();
System.out.println(result); // 1,2,3,4,5,
// Лучше использовать collect
String resultBetter = numbers.stream()
.map(String::valueOf)
.collect(Collectors.joining(","));
System.out.println(resultBetter); // 1,2,3,4,5
Разница между reduce и collect
| Операция | reduce | collect |
|---|---|---|
| Назначение | Свертка потока в одно значение | Накопление в контейнер |
| Тип результата | Один элемент или Optional | Коллекция или контейнер |
| Параллелизм | Требует стороннего combiner | Встроенная поддержка параллелизма |
| Производительность | Может быть медленнее для параллельных потоков | Оптимизирована для параллелизма |
// reduce
int sum = numbers.stream()
.reduce(0, Integer::sum);
// collect (лучше для сборки)
List<Integer> doubled = numbers.stream()
.map(n -> n * 2)
.collect(Collectors.toList());
Использование в параллельных потоках
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// Работает безопасно с параллельными потоками
int sum = numbers.parallelStream()
.reduce(
0,
Integer::sum, // accumulator
Integer::sum // combiner для объединения результатов
);
System.out.println(sum); // 55
Таким образом, reduce в Stream API предоставляет мощный инструмент для трансформации потока данных в одно агрегированное значение, поддерживая как последовательные, так и параллельные обработки.