Операції відомості. Метод reduce
Операції відомості. Метод reduce – онлайн курс джава
Операції зведення. Метод `reduce` в Stream API
Операції зведення в Stream API використовуються для об’єднання елементів потоку в єдиний результат, наприклад, для обчислення суми, добутку, об’єднання рядків тощо. Основним методом для цього є `reduce()`.
Що таке метод `reduce`?
Метод `reduce()` зводить елементи потоку до одного значення, застосовуючи до них асоціативну операцію. Він обробляє елементи послідовно або паралельно залежно від типу потоку (послідовного чи паралельного) і повертає результат цієї операції.
Синтаксис методу `reduce`:
Optional<T> reduce(BinaryOperator<T> accumulator);
T reduce(T identity, BinaryOperator<T> accumulator);
<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);
Давайте розглянемо три варіанти використання методу `reduce()`:
1. Використання `reduce(BinaryOperator<T> accumulator)`
У цьому варіанті `reduce()` застосовує бінарну операцію до двох елементів потоку, поступово об’єднуючи їх. Якщо потік порожній, результатом буде `Optional.empty()`.
Приклад обчислення суми елементів:
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// Зводимо елементи до одного значення (суми)
Optional<Integer> sum = numbers.stream()
.reduce((a, b) -> a + b);
sum.ifPresent(result -> System.out.println(“Сума: ” + result));
}
}
Виведення:
Сума: 15
У цьому прикладі `reduce()` поступово об’єднує елементи: спочатку обчислюється сума перших двох елементів, потім результат додається до наступного елемента і так далі.
2. Використання `reduce(T identity, BinaryOperator<T> accumulator)`
Цей варіант надає початкове значення (identity), яке використовується як стартове значення для операції. Це гарантує, що результат не буде порожнім, навіть якщо потік порожній.
Приклад обчислення добутку елементів:
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// Зводимо елементи до одного значення (добутку), починаючи з 1
int product = numbers.stream()
.reduce(1, (a, b) -> a * b);
System.out.println(“Добуток: ” + product);
}
}
Виведення:
Добуток: 120
У цьому прикладі початкове значення — це 1, і далі застосовується бінарна операція множення.
3. Використання `reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner)`
Цей варіант підходить для паралельної обробки потоків і дозволяє комбінувати результати обчислень. Перший параметр `identity` — це початкове значення, другий — це функція для обробки елементів, а третій — це комбінатор, що поєднує результати.
Приклад об’єднання рядків:
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> words = Arrays.asList(“Java”, “Stream”, “API”, “Reduce”);
// Об’єднуємо рядки у один рядок з пропусками між ними
String combinedString = words.stream()
.reduce(“”, (a, b) -> a + ” ” + b);
System.out.println(“Об’єднаний рядок: ” + combinedString.trim());
}
}
Виведення:
Об’єднаний рядок: Java Stream API Reduce
У цьому прикладі ми використовуємо `reduce()` для об’єднання рядків із пробілами між ними. Початкове значення — порожній рядок, а потім кожен рядок додається до результату.
Особливості операції зведення
- Ассоціативність: Операція, яку використовують у `reduce()`, повинна бути асоціативною, тобто порядок обробки елементів не має впливати на результат. Наприклад, додавання та множення — асоціативні операції, а віднімання чи ділення — ні.
- Порожній потік: Якщо використовується варіант без початкового значення, результат буде обгорткою `Optional<T>`, і його слід перевірити на наявність значення.
Застосування `reduce()` для різних операцій
- Сума елементів:
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b); - Максимальне значення:
Optional<Integer> max = numbers.stream()
.reduce(Integer::max); - Лічильник кількості елементів (аналог методу `count()`):
long count = numbers.stream()
.reduce(0, (count, element) -> count + 1, Integer::sum);
Висновок
Метод `reduce()` дозволяє виконувати операції зведення на потоках даних і є потужним інструментом для роботи з колекціями. Основні варіанти використання включають обчислення суми, добутку, об’єднання рядків та інших операцій.