Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Вивчайте Агрегування Елементів за Допомогою Методу reduce() | Термінальні Операції у Stream API
Practice
Projects
Quizzes & Challenges
Вікторини
Challenges
/
Stream API

bookАгрегування Елементів за Допомогою Методу reduce()

Свайпніть щоб показати меню

Під час роботи з колекціями у Java часто виникає потреба згрупувати всі елементи в один результат, наприклад, суму, добуток або інше агреговане значення.

Існує три варіанти методу reduce(), кожен з яких призначений для різних сценаріїв. Розглянемо кожен з них детальніше.

reduce() з одним параметром

Якщо потрібно агрегувати елементи без початкового значення, можна використати цю версію reduce(). Оскільки потік може бути порожнім, метод повертає Optional<T>.

Optional<T> reduce(BinaryOperator<T> accumulator);

Цей метод застосовує функцію accumulator до всіх елементів потоку та повертає Optional<T>.

Практичний приклад

Уявіть інтернет-магазин зі списком товарів та їх цін. Мета — обчислити загальний дохід від усіх товарів у магазині.

Main.java

Main.java

copy
1234567891011121314151617181920212223242526272829303132333435363738
package com.example; import java.util.List; import java.util.Optional; public class Main { public static void main(String[] args) { List<Product> products = List.of( new Product("Laptop", 1200.0), new Product("Mouse", 25.0), new Product("Keyboard", 75.0) ); Optional<Double> totalRevenue = products.stream() .map(Product::getPrice) .reduce(Double::sum); totalRevenue.ifPresent(revenue -> System.out.println("Total revenue: " + revenue)); } } class Product { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } }

Цей код створює список продуктів, а потім використовує reduce() для підсумовування цін. Метод map(Product::getPrice) витягує ціну кожного продукту, а Double::sum виконує додавання. Якщо результат присутній, він виводиться.

reduce() з двома параметрами

Щоб забезпечити гарантоване повернення значення, навіть якщо потік є порожнім, використовуйте метод reduce() з ідентифікуючим параметром. Початкове значення гарантує стабільність обчислення.

T reduce(T identity, BinaryOperator<T> accumulator);

Ця версія reduce() починається з заданого значення identity, що гарантує отримання результату навіть для порожнього потоку.

Практичний приклад

Припустимо, що у магазині є каса з початковим балансом, і потрібно додати загальну вартість усіх товарів, щоб визначити потенційну загальну суму готівки.

Main.java

Main.java

copy
12345678910111213141516171819202122232425262728293031323334353637
package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<Product> products = List.of( new Product("Laptop", 1200.0), new Product("Mouse", 25.0), new Product("Keyboard", 75.0) ); double totalRevenue = products.stream() .map(Product::getPrice) .reduce(500.0, Double::sum); System.out.println("Total revenue with initial balance: " + totalRevenue); } } class Product { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } }

Тут код витягує ціни за допомогою map(Product::getPrice) і застосовує reduce(500.0, Double::sum), де 500.0 означає початковий баланс, а Double::sum підсумовує значення.

reduce() для паралельної обробки

Ця версія reduce() призначена для випадків, коли потрібні більш складні перетворення і результати необхідно агрегувати у паралельному режимі.

<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);

Цей метод приймає три параметри:

  • identityпочаткове значення;
  • accumulator – функція, яка перетворює кожен елемент;
  • combiner – функція, яка об'єднує часткові результати.

Практичний приклад

В інтернет-магазині необхідно обчислити загальну кількість символів у всіх назвах товарів. Це може бути корисно для встановлення обмежень на довжину чека.

Main.java

Main.java

copy
123456789101112131415161718192021222324252627282930313233343536
package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<Product> products = List.of( new Product("Laptop", 1200.0), new Product("Mouse", 25.0), new Product("Keyboard", 75.0) ); int totalLength = products.stream() .reduce(0, (sum, product) -> sum + product.getName().length(), Integer::sum); System.out.println("Total name length: " + totalLength); } } class Product { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } }

Код ітерує через список продуктів за допомогою reduce(), де 0 — це початкове значення, (sum, product) -> sum + product.getName().length() визначає логіку для підсумовування довжин імен продуктів, а Integer::sum об'єднує результати у середовищі паралельної обробки.

1. Який тип даних повертає reduce(BinaryOperator<T> accumulator), якщо потік може бути порожнім?

2. Коли слід використовувати reduce(T identity, BinaryOperator<T> accumulator)?

question mark

Який тип даних повертає reduce(BinaryOperator<T> accumulator), якщо потік може бути порожнім?

Select the correct answer

question mark

Коли слід використовувати reduce(T identity, BinaryOperator<T> accumulator)?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 3. Розділ 6

Запитати АІ

expand

Запитати АІ

ChatGPT

Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат

Секція 3. Розділ 6
some-alt