JavaRush /Курси /Java Syntax Zero /Робота з потоками, частина 1

Робота з потоками, частина 1

Java Syntax Zero
Рівень 19 , Лекція 4
Відкрита

1. Список методів типу Stream

Клас Stream було створено для того, щоб можна було легко конструювати ланцюжки потоків даних. Для цього об'єкт типу Stream<T> має методи, що повертають нові об'єкти типу Stream.

Кожен із цих потоків даних уміє виконувати одну просту дію, натомість, якщо їх об'єднати в ланцюжки та ще й додати до цього таку цікаву річ, як лямбда-функції, на виході можна отримати дуже потужний інструмент. Незабаром ви самі в цьому переконаєтеся.

Отакі методи має клас Stream (наводимо лише основні):

Методи Опис
Stream<T> of()
Створює потік з набору об'єктів
Stream<T> generate()
Генерує потік за встановленим правилом
Stream<T> concat()
З'єднує кілька потоків
Stream<T> filter()
Фільтрує дані: пропускає тільки дані, що відповідають встановленому правилу
Stream<T> distinct()
Видаляє дублікати: не пропускає дані, що вже були
Stream<T> sorted()
Сортує дані
Stream<T> peek()
Виконує дію над кожним елементом даних
Stream<T> limit(n)
Обрізає дані після досягнення ліміту
Stream<T> skip(n)
Пропускає перші n елементів даних
Stream<R> map()
Перетворює дані з одного типу на інший
Stream<R> flatMap()
Перетворює дані з одного типу на інший
boolean anyMatch()
Перевіряє, чи є серед елементів даних потоку щонайменше один, який відповідає встановленому правилу
boolean allMatch()
Перевіряє, чи всі дані в потоці відповідають установленому правилу
boolean noneMatch()
Перевіряє, чи жоден елемент даних у потоці не відповідає встановленому правилу
Optional<T> findFirst()
Повертає перший знайдений елемент, який відповідає правилу
Optional<T> findAny()
Повертає з потоку будь-який елемент, який відповідає правилу
Optional<T> min()
Шукає найменший елемент у потоці даних
Optional<T> max()
Повертає найбільший елемент у потоці даних
long count()
Повертає кількість елементів у потоці даних
R collect()
Зчитує всі дані з потоку й повертає їх у вигляді колекції

2. Створення потоків

Серед методів класу Stream є три, котрі ми ще не розглянули. Завдання цих трьох методів — створювати нові потоки.

Метод Stream<T>.of(T obj)

Метод of() створює потік, який складається з одного елемента. Зазвичай це потрібно, коли, припустімо, функція отримує як параметр об'єкт типу Stream<T>, а у вас є тільки об'єкт типу T. Тоді ви можете легко й просто за допомогою методу of() отримати потік, який складається з одного елемента.

Приклад:

Stream<Integer> stream = Stream.of(1);

Метод Stream<T> Stream.of(T obj1, T obj2, T obj3, …)

Метод of() створює потік, який складається з переданих елементів. Кількість елементів може бути будь-якою. Приклад:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);

Метод Stream<T> Stream.generate(Supplier<T> obj)

Метод generate() дає змогу встановити правило, за яким генеруватиметься черговий елемент потоку під час запиту цього елемента. Наприклад, можна щоразу віддавати випадкове число.

Приклад:

Stream<Double> s = Stream.generate(Math::random);

Метод Stream<T> Stream.concat(Stream<T> a, Stream<T> b)

Метод concat() з'єднує два передані потоки в один. Під час читання даних спочатку буде прочитано дані з першого потоку, а потім із другого. Приклад:

Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> stream2 = Stream.of(10, 11, 12, 13, 14);
Stream<Integer> result = Stream.concat(stream1, stream2);

3. Фільтрування даних

Ще 6 методів створюють нові потоки даних, які дають змогу з'єднувати потоки в ланцюжки різної складності.

Метод Stream<T> filter(Predicate<T>)

Цей метод повертає новий потік даних, який фільтрує дані з потоку-джерела згідно з переданим правилом. Метод потрібно викликати для об'єкта типу Stream<T>.

Для встановлення правила фільтрування можна використовувати лямбда-функцію, яку компілятор потім перетворить на об'єкт типу Predicate<T>.

Приклади:

Ланцюжки потоків Пояснення
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> stream2 = stream.filter(x -> (x < 3));

Залишаємо тільки числа, менші за 3
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
Stream<Integer> stream2 = stream.filter(x -> (x > 0));

Залишаємо тільки числа, більші за нуль

Метод Stream<T> sorted(Comparator<T>)

Цей метод повертає новий потік даних, який сортує дані з потоку-джерела. Як параметр можна передати компаратор, який буде встановлювати правила порівняння двох елементів потоку даних.

Метод Stream<T> distinct()

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

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 2, 2, 2, 3, 4);
Stream<Integer> stream2 = stream.distinct(); // 1, 2, 3, 4, 5

Метод Stream<T> peek(Consumer<T>)

Цей метод повертає новий потік даних, хоча дані в ньому ті самі, що й у потоці-джерелі. Однак під час запиту чергового елемента з потоку для цього елемента викликається функція, яку ви передали в метод peek().

Якщо в метод peek() передати функцію system.out::println, тоді всі об'єкти виводитимуться на екран у той момент, коли вони проходитимуть через потік.

Метод Stream<T> limit(int n)

Цей метод повертає новий потік даних, який містить лише перші n елементів даних з потоку даних джерела. Решта даних відкидається. Приклад:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 2, 2, 2, 3, 4);
Stream<Integer> stream2 = stream.limit(3); // 1, 2, 3

Метод Stream<T> skip(int n)

Цей метод повертає новий потік даних, який містить усі ті самі дані, що й потік-джерело, але пропускає (ігнорує) перші n елементів даних. Приклад:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 2, 2, 2, 3, 4);
Stream<Integer> stream2 = stream.skip(3); // 4, 5, 2, 2, 2, 3, 4

Коментарі (8)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Sava_crosava Рівень 23
3 листопада 2023
Дивно що тут ніхто не вициганює лайки) Після коментарів під попередньою лекцією аж дивно стало)
12 травня 2025
Ну якщо ти наполягаєш, то можете мені насипати, якщо не шкода))
Олег Рівень 111 Expert
8 серпня 2023
та ні, ви шо, з моїми знаннями з java-університету ці задачі просто космічні )
kalkulator¹ Рівень 51
26 листопада 2022
тільки коли пройшов задачі зрозумів все про лямбда вирази
FAUST_ua Рівень 29
3 жовтня 2022
Ага, іще рекомендую почитати статті на stackoverflow
Сергій Ситюк Рівень 21
2 липня 2022
Деякі лекції варто переглянути. Занадто складно подаються дуже прості речі. Варто було б додати в лекції приклад типу ArrayList.stream().distinct(), як відразу все стає зрозуміло.
RomanH Рівень 29
20 січня 2022
Між 1 і 2 підрозділами пропущено "Intermediate и terminal методы Stream". Раджу прочиитати ще Syntax Pro
Olia H Рівень 28
19 січня 2022
З лекції було мало що зрозуміло. Потім в задачках зрозуміла, що взагалі нічого не зрозуміло😅😅😅 А виявляється (спойлер) все можна вирішити одним словом "stream()" . Раджу після цієї лекції почитати ще відповідну на Syntax Pro.