от aNNiMON
Если вы заметили ошибку, нажмите Shift+Enter, чтобы сообщить о ней.
Все ваши сообщения можно посмотреть здесь.
Полное руководство по Java 8 Stream API в картинках и примерах
С момента выхода Java 8 я практически сразу начал пользоваться Stream API, так как функциональный подход обработки данных мне пришелся по нраву. Хотелось пользоваться им везде, поэтому я начал разрабатывать библиотеку Lightweight-Stream-API, которая привносит подобный подход в ранние версии Java. Также меня интересовало внутреннее устройство стримов. За это время накопилось достаточно опыта и теперь я спешу им поделиться.
В статье, помимо описания стримов, приводятся визуальные демонстрации работы операторов, примеры и задачи для самопроверки. Также затронуты нововведения, касающиеся стримов в Java 9.
Дабы не путать стримы (Stream) с I/O потоками (InputStream/OutputStream) и тредами/нитями/потоками (Thread), я буду придерживаться англоязычного именования в транслите и называть Stream стримом.
Stream — это объект для универсальной работы с данными. Мы указываем, какие операции хотим провести, при этом не заботясь о деталях реализации. Например, взять элементы из списка сотрудников, выбрать тех, кто младше 40 лет, отсортировать по фамилии и поместить в новый список. Или чуть сложнее, прочитать все json-файлы, находящиеся в папке books, десериализировать в список объектов книг, обработать элементы всех этих списков, а затем сгруппировать книги по автору.
Данные могут быть получены из источников, коими являются коллекции или методы, поставляющие данные. Например, список файлов, массив строк, метод range() для числовых промежутков и т.д. То есть, стрим использует существующие коллекции для получения новых элементов, это ни в коем случае не новая структура данных.
К данным затем применяются операторы. Например, взять лишь некоторые элементы (filter), преобразовать каждый элемент (map), посчитать сумму элементов или объединить всё в один объект (reduce).
Операторы можно разделить на две группы:
- Промежуточные (intermediate) — обрабатывают поступающие элементы и возвращают стрим. Промежуточных операторов в цепочке обработки элементов может быть много.
- Терминальные (terminal) — обрабатывают элементы и завершают работу стрима, так что терминальный оператор в цепочке может быть только один.
В статье, помимо описания стримов, приводятся визуальные демонстрации работы операторов, примеры и задачи для самопроверки. Также затронуты нововведения, касающиеся стримов в Java 9.
Дабы не путать стримы (Stream) с I/O потоками (InputStream/OutputStream) и тредами/нитями/потоками (Thread), я буду придерживаться англоязычного именования в транслите и называть Stream стримом.
1. Stream
Stream — это объект для универсальной работы с данными. Мы указываем, какие операции хотим провести, при этом не заботясь о деталях реализации. Например, взять элементы из списка сотрудников, выбрать тех, кто младше 40 лет, отсортировать по фамилии и поместить в новый список. Или чуть сложнее, прочитать все json-файлы, находящиеся в папке books, десериализировать в список объектов книг, обработать элементы всех этих списков, а затем сгруппировать книги по автору.
Данные могут быть получены из источников, коими являются коллекции или методы, поставляющие данные. Например, список файлов, массив строк, метод range() для числовых промежутков и т.д. То есть, стрим использует существующие коллекции для получения новых элементов, это ни в коем случае не новая структура данных.
К данным затем применяются операторы. Например, взять лишь некоторые элементы (filter), преобразовать каждый элемент (map), посчитать сумму элементов или объединить всё в один объект (reduce).
Операторы можно разделить на две группы:
- Промежуточные (intermediate) — обрабатывают поступающие элементы и возвращают стрим. Промежуточных операторов в цепочке обработки элементов может быть много.
- Терминальные (terminal) — обрабатывают элементы и завершают работу стрима, так что терминальный оператор в цепочке может быть только один.