JavaRush /Курсы /Java Syntax Pro /Потоки данных

Потоки данных

Java Syntax Pro
18 уровень, 2 лекция
Открыта

1. Нововведения в Java 8: Функциональное программирование

Вместе с выходом Java 8 в ней появилась мощная поддержка функционального программирования. Можно даже сказать, долгожданная поддержка функционального программирования. Код стал писаться быстрее, хотя читать его стало сложнее 🙂

Перед изучением функционального программирования в Java, рекомендуем хорошо разобраться в трех вещах:

  1. ООП, наследование и интерфейсы (1-2 уровни квеста Java Core).
  2. Дефолтная реализация методов в интерфейсе.
  3. Внутренние и анонимные классы.

Хорошая новость заключается в том, что без знания всего этого можно пользоваться многими возможностями функционального программирования в Java. Плохая новость — понять, как именно все устроено и как все работает, без тех же внутренних анонимных классов уже сложно.

В ближайших лекциях мы сосредоточимся на том, как легко и просто пользоваться возможностями функционального программирования в Java, без глубокого понимания, как оно устроено.

Чтобы разобраться во всех нюансах функционального программирования в Java, нужны месяцы. Читать же такой код можно научиться за несколько часов. Поэтому предлагаем начать с малого. Да хоть с тех же потоков ввода-вывода.


2. Потоки ввода-вывода: цепочки потоков

Помните, когда-то вы изучали потоки ввода-вывода: InputStream, OutputStream, Reader, Writer и т.п.?

Были классы-потоки, которые читали данные из источников данных, такие как FileInputSteam, а были и промежуточные потоки данных, которые читали данные из других потоков, такие как InputStreamReader и BufferedReader.

Эти потоки можно было организовывать в цепочки обработки данных. Например, так:

FileInputStream input = new FileInputStream("c:\\readme.txt");
InputStreamReader reader = new InputStreamReader(input);
BufferedReader buff = new BufferedReader(reader);

String text = buff.readLine();

Важно отметить, что в первых нескольких строках кода мы просто конструируем цепочку из Stream-объектов, но реальные данные по этой цепочке потоков еще не передаются.

И только когда мы вызовем метод buff.readLine(), произойдет следующее:

  1. Объект BufferedReader вызовет метод read() у объекта InputStreamReader
  2. Объект InputStreamReader вызовет метод read() у объекта FileInputStream
  3. Объект FileInputStream начнет читать данные из файла

Т.е. никакого движения данных по цепочке потоков нет, пока мы не начали вызывать методы типа read() или readLine(). Само конструирование цепочки потоков данные по ним не гоняет. Потоки сами данные не хранят, а только читают из других.

Коллекции и потоки

Начиная с Java 8, появилась возможность получить поток для чтения данных у коллекций (и не только у них). Но и это еще не самое интересное. На самом деле появилась возможность легко и просто конструировать сложные цепочки потоков данных, при этом тот код, который раньше требовал 5-10 строк, теперь можно было записать в 1-2 строки.

Пример — находим строку максимальной длины в списке строк:

Поиск строки максимальной длины
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Привет", "как", "дела?");
String max = list.stream().max((s1, s2)-> s1.length()-s2.length()).get();
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Привет", "как", "дела?");
Stream<String> stream = list.stream();
Optional<String> optional = stream.max((s1, s2)-> s1.length()-s2.length());
String max = optional.get();

3. Интерфейс Stream

Расширенная поддержка потоков в Java 8 реализована с помощью интерфейса Stream<T>. Где T — это тип-параметр, обозначающий тип данных, которые передаются в потоке. Другими словами, поток полностью независим от типа данных, которые он передает.

Чтобы получить объект-поток у коллекции, достаточно вызвать у нее метод stream(). Выглядит этот код примерно так:

Stream<Тип> имя = коллекция.stream();
Получение потока из коллекции

При этом коллекция будет считаться источником данных потока, а объект типа Stream<Тип> – инструментом по получению данных из коллекции именно в виде потока данных.

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Привет", "как", "дела?");
Stream<String> stream = list.stream();

Кстати, можно получить поток не только у коллекции, но и у массива. Для этого нужно воспользоваться методом Arrays.stream(); Пример:

Stream<Тип> имя = Arrays.stream(массив);
Получение потока из массива

При этом массив будет считаться источником данных для потока имя.

Integer[] array = {1, 2, 3};
Stream<Integer> stream = Arrays.stream(array);

После создания объекта Stream<Тип> никакого движения данных не происходит. Мы просто получили объект-поток для того, чтобы начать строить цепочку из потоков-данных.


Комментарии (196)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Euraks Уровень 33
8 октября 2026
🦔
Grigoryvvv Уровень 28 Expert
27 июля 2026
27.07.2026 / 19 уровень
Win32Trojan Уровень 2
1 августа 2026
Начинаю наступать на пятки)
Grigoryvvv Уровень 28 Expert
1 августа 2026
Это не мои пятки ))
Игорь Лупац Уровень 48
16 мая 2026
Порекомендую книгу "Современный язык Java. Лямбда-выражения, потоки и функциональное программирование" Урма Р., Фуско М., Майкрофт А.
C0N5P1RACY Уровень 42
8 января 2026

 Потоки ввода-вывода: цепочки потоков
Виктор Уровень 28
29 сентября 2025
ооо блин, вот и встретились жаба с гадюкой, ещё черепаха.
Den Winchester Уровень 32
28 сентября 2025

Помните, когда-то вы изучали потоки ввода-вывода: InputStream, OutputStream, Reader, Writer и т.п.?
Кто всё ещё не понял данные темы, советую посмотреть на youtube уроки alisheva: Java для начинающих. Урок 45-47 Сериализация
Anonymous #3585174 Уровень 33
23 июля 2025
like
Рифати Уровень 2
5 июля 2025
5 апреля 2025
"Помните, когда-то вы изучали потоки ввода-вывода: InputStream, OutputStream, Reader, Writer и т.п.?" ...Оно снова настигло меня
Что то подозрительно легко решаются задачи 🤔