Java Streams (Потоки в Java) надають гнучкий та ефективний спосіб обробки даних, але вони не обмежуються тільки ітераціями або прив’язані до колекцій Java. Потоки також не є рекурсивними, а ітеративними, розроблені для функціонального стилю програмування, що робить обробку даних стислою та потужною. Давайте розглянемо, як потоки створюються та використовуються з різними джерелами.
Оновлений приклад коду
package com.translateIdea2Code.streams;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class StreamsDemo {
public static void main(String[] args) throws IOException {
// Приклад 1: Створення потоку з List
List names = List.of("raj", "ram", "vinod", "rahul");
Stream stream = names.stream(); // Створення потоку з List
stream.forEach(System.out::println); // Ітерація та виведення елементів
// Приклад 2: Створення потоку з масиву
int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Arrays.stream(numbers).forEach(System.out::println); // Потік з масиву
// Приклад 3: Використання Stream.of для безпосереднього створення потоку
Stream.of("mango", "banana", "strawberry", "apple", "orange", "pineapple")
.forEach(System.out::println);
// Приклад 4: Використання вбудованих API, які повертають потоки
Stream lines = Files.lines(Paths.get("README.md")); // Потік з рядків файлу
lines.forEach(System.out::println);
// Приклад 5: Генерація потоку за допомогою Stream.generate
Stream.generate(Math::random) // Генерація нескінченного потоку випадкових чисел
.limit(10) // Обмеження потоку до 10 елементів
.forEach(System.out::println);
// Приклад 6: Генерація потоку за допомогою Stream.iterate
Stream.iterate(0, x -> x + 2) // Генерація нескінченного потоку парних чисел
.limit(10) // Обмеження потоку до 10 елементів
.forEach(System.out::println);
}
}
Основні моменти
1. Потоки не прив’язані до колекцій
Потоки можна створювати з різноманітних джерел, включаючи:
- Колекції (наприклад,
List
,Set
,Map
) - Масиви (наприклад,
Arrays.stream(array)
) - Користувацькі генератори (наприклад,
Stream.generate
,Stream.iterate
) - Файлові API (наприклад,
Files.lines(Path)
)
Ця універсальність робить потоки надзвичайно потужними та незалежними від конкретного типу джерела даних.
2. Потоки ітеративні, а не рекурсивні
Потоки використовують ітерацію замість рекурсії для обробки елементів. Така конструкція забезпечує кращу продуктивність та уникає проблеми переповнення стека, з якими можуть стикатися рекурсивні алгоритми при обробці великих наборів даних.
3. Потоки одноразові
Після того, як потік спожито (через термінальну операцію, як-от forEach
), його неможливо використовувати знову. Завжди створюйте новий потік для додаткових операцій.
Коли використовувати потоки
Потоки ідеально підходять для обробки даних у функціональному та декларативному стилі. Вони особливо корисні для таких задач, як:
- Фільтрація (наприклад,
stream.filter(predicate)
) - Трансформація (наприклад,
stream.map(function)
) - Агреґація (наприклад,
stream.reduce(identity, accumulator)
)
Зрозумівши гнучкість і обмеження Java Streams, ви зможете ефективно використовувати їх для написання чистого та ефективного коду.
Перекладено з: Understanding Java Streams: Beyond Collections and Iterability