Агрегування Елементів за Допомогою Методу reduce()
Під час роботи з колекціями у Java часто виникає потреба згрупувати всі елементи в один результат, наприклад, суму, добуток або інше агреговане значення.
Існує три варіанти методу reduce(), кожен з яких призначений для різних сценаріїв. Розглянемо кожен з них детальніше.
reduce() з одним параметром
Якщо потрібно агрегувати елементи без початкового значення, можна використати цю версію reduce(). Оскільки потік може бути порожнім, метод повертає Optional<T>.
Optional<T> reduce(BinaryOperator<T> accumulator);
Цей метод застосовує функцію accumulator до всіх елементів потоку та повертає Optional<T>.
Практичний приклад
Уявіть інтернет-магазин зі списком товарів та їх цін. Мета — обчислити загальний дохід від усіх товарів у магазині.
Main.java
1234567891011121314151617181920212223242526272829303132333435363738package 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
12345678910111213141516171819202122232425262728293031323334353637package 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
123456789101112131415161718192021222324252627282930313233343536package 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)?
Дякуємо за ваш відгук!
Запитати АІ
Запитати АІ
Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат
Awesome!
Completion rate improved to 2.33
Агрегування Елементів за Допомогою Методу reduce()
Свайпніть щоб показати меню
Під час роботи з колекціями у Java часто виникає потреба згрупувати всі елементи в один результат, наприклад, суму, добуток або інше агреговане значення.
Існує три варіанти методу reduce(), кожен з яких призначений для різних сценаріїв. Розглянемо кожен з них детальніше.
reduce() з одним параметром
Якщо потрібно агрегувати елементи без початкового значення, можна використати цю версію reduce(). Оскільки потік може бути порожнім, метод повертає Optional<T>.
Optional<T> reduce(BinaryOperator<T> accumulator);
Цей метод застосовує функцію accumulator до всіх елементів потоку та повертає Optional<T>.
Практичний приклад
Уявіть інтернет-магазин зі списком товарів та їх цін. Мета — обчислити загальний дохід від усіх товарів у магазині.
Main.java
1234567891011121314151617181920212223242526272829303132333435363738package 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
12345678910111213141516171819202122232425262728293031323334353637package 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
123456789101112131415161718192021222324252627282930313233343536package 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)?
Дякуємо за ваш відгук!