Получи случайную криптовалюту за регистрацию!

Stream API: новые методы в Java 16 16 марта выйдет java 16. Н | Java: fill the gaps

Stream API: новые методы в Java 16

16 марта выйдет java 16. Новые фичи входят во вторую превью стадию перед главным релизом 2021 - java 17 LTS.

Существующие классы тоже развиваются. В java 16 в Stream API появилось 4 новых метода, которые мы и рассмотрим в этом посте.

toList()

С 25 по 27 ноября была серия постов о коллекторах (часть 1, часть 2, часть 3). Там я писала, что вместо

collect(Collectors.toList())
было бы удобно писать просто
toList()

30 ноября разработчик Oracle добавил метод toList() в класс Stream. Вряд ли он читает этот канал, но совпадение интересное

Новый метод не совсем равнозначный:
Collectors.toList() возвращает экземпляр ArrayList.
Новый метод toList() возвращает неизменяемый список.

mapMulti

Это оптизированный flatMap. Объясню суть на примере. Заказ - класс Order, товар - класс Item. Заказ состоит из нескольких товаров. Из списка заказов хотим получить список всех товаров.

orders.stream()
.flatMap(order->order.getItems().stream())
.toList();

flatMap переводит "список списков" в один список. Товары для каждого заказа превращаются в Stream, а метод flatMap объединяет эти стримы в один.

Минус: объект стрима создаётся всегда, даже для пустых списков.

mapMulti устраняет этот недостаток:

orders.stream()
.mapMulti((order, consumer) ->
order.getItems().forEach(item -> consumer.accept(item))
).toList();

Что происходит:
mapMulti принимает на вход (order, consumer):
order - элемент стрима, в нашем случае - заказ
consumer - следующий этап в стриме. Наша задача - передать этому этапу все будущие элементы. Берём у заказа товары и для каждого вызываем consumer.accept(item).

Мультимэп не знает, для каких объектов будет вызван accept, и не может вывести тип выходных элементов. Поэтому для нормальной работы тип надо указать явно:

mapMulti(…)

Когда использовать mapMulti?

Небольшое количество элементов в списках.
Например, много заказов с 1-2 товарами

Элементы легко получить без Stream API
Основная фишка mapMulti - нет промежуточных стримов. Если внутри метода создаётся стрим, то вся выгода сходит на нет.
order.getItems().stream()…

Есть три вариации метода:
IntStream mapMultiToInt
LongStream mapMultiToLong
DoubleStream mapMultiToDouble

Для них выходной тип не указывается.