Введення в Stream API. Створення потоку даних

Прокрутити вниз

Введення в Stream API. Створення потоку даних – уроки java

Введення в Stream API у Java

Stream API було введено в Java 8 і призначене для роботи з колекціями даних у функціональному стилі. Потоки дозволяють обробляти дані декларативно (через послідовні операції) і підтримують такі можливості, як фільтрація, сортування, перетворення елементів, а також агрегування даних. Stream API полегшує обробку великих обсягів даних завдяки можливості використовувати як послідовні, так і паралельні операції.

Основні концепції Stream API

  1. Потік (Stream) — це послідовність елементів, яка підтримує лінейні операції, що можуть обробляти дані без збереження їх у пам’яті. Потоки не змінюють джерела даних (тобто вони не змінюють колекцію, з якої беруться елементи).
  2. Ліниві обчислення — потоки підтримують ланцюгові операції, що виконуються тільки тоді, коли запускається кінцева операція (наприклад, `collect()`, `forEach()` тощо).
  3. Типи операцій:
    • Проміжні (intermediate): ці операції виконуються при обробці даних і повертають новий потік (наприклад, `map()`, `filter()`, `sorted()`).
    • Кінцеві (terminal): ці операції запускають обробку всього потоку і повертають результат (наприклад, `collect()`, `forEach()`, `count()`).

Створення потоку даних

Потоки можуть бути створені з різних джерел даних, таких як колекції, масиви, файли та інші ресурси. Найпоширеніший спосіб — це створення потоку з колекцій або масивів.

Створення потоку з колекцій

Метод `stream()` використовується для створення потоку з колекцій (наприклад, `List`, `Set` тощо).

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class Main {
public static void main(String[] args) {
// Створюємо список
List<String> names = Arrays.asList(“Андрій”, “Ольга”, “Іван”, “Марія”);

// Створюємо потік з колекції
Stream<String> nameStream = names.stream();

// Обробляємо потік: фільтруємо і виводимо на екран
nameStream
.filter(name -> name.startsWith(“А”))
.forEach(System.out::println);
}
}

Виведення:

Андрій

У цьому прикладі ми створюємо потік з колекції `List`, фільтруємо імена, які починаються на букву “А”, і виводимо їх на екран за допомогою кінцевої операції `forEach()`.

Створення потоку з масивів

Для створення потоку з масивів використовується метод `Arrays.stream()` або метод `Stream.of()`.

import java.util.stream.Stream;

public class Main {
public static void main(String[] args) {
// Створюємо масив
String[] names = {“Олег”, “Аня”, “Максим”, “Дмитро”};

// Створюємо потік з масиву
Stream<String> nameStream = Stream.of(names);

// Обробляємо потік: фільтруємо і виводимо на екран
nameStream
.filter(name -> name.length() > 4)
.forEach(System.out::println);
}
}

Виведення:

Максим
Дмитро

Створення нескінченних потоків

За допомогою методу `Stream.generate()` або `Stream.iterate()` можна створювати нескінченні потоки. Це корисно, якщо потрібно працювати з нескінченними послідовностями даних.

import java.util.stream.Stream;

public class Main {
public static void main(String[] args) {
// Створюємо нескінченний потік за допомогою iterate()
Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 2);

// Обмежуємо кількість елементів і виводимо їх на екран
infiniteStream
.limit(5)
.forEach(System.out::println);
}
}

Виведення:

0
2
4
6
8

Основні операції з потоками

  1. `filter(Predicate)` — фільтрує елементи потоку на основі умови.
    stream.filter(s -> s.length() > 3);
  2. `map(Function)` — перетворює елементи потоку.
    stream.map(String::toUpperCase);
  3. `sorted()` — сортує елементи потоку.
    stream.sorted();
  4. `distinct()` — видаляє дублікати.
    stream.distinct();
  5. `limit(n)` — обмежує кількість елементів у потоці.
    stream.limit(5);
  6. `skip(n)` — пропускає перші `n` елементів у потоці.
    stream.skip(3);
  7. Кінцеві операції:`forEach(Consumer)` — виконує дію для кожного елемента потоку.
    stream.forEach(System.out::println);
  8. `collect(Collector)` — збирає елементи потоку в колекцію або іншу структуру даних.
    List<String> result = stream.collect(Collectors.toList());
  9. `count()` — повертає кількість елементів у потоці.
    long count = stream.count();
  10. `reduce(BinaryOperator)` — агрегує елементи потоку в одне значення.
    int sum = stream.reduce(0, Integer::sum);

Паралельні потоки

Паралельні потоки використовуються для розподілу обробки даних між кількома потоками, що може суттєво збільшити продуктивність при роботі з великими колекціями.

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, 6, 7, 8, 9, 10);

// Створюємо паралельний потік
int sum = numbers.parallelStream()
.filter(n -> n % 2 == 0)
.reduce(0, Integer::sum);

System.out.println(“Сума парних чисел: ” + sum);
}
}

Виведення:

Сума парних чисел: 30

У цьому прикладі використовуються паралельні потоки для ефективної обробки чисел. Потік розподіляє обробку між кількома потоками JVM.

Висновок

Stream API — це потужний інструмент для обробки даних у функціональному стилі. Він дозволяє легко виконувати операції над колекціями, фільтрувати, перетворювати, агрегувати дані та працювати з великими обсягами інформації більш ефективно завдяки паралельним потокам.

Введення в Stream API. Створення потоку даних