16 марта вышла java 16. Новые фичи входят во вторую превью стадию перед главным релизом 2021 - java 17 LTS.
Существующие классы тоже развиваются. В java 16 в Stream API появилось 4 новых метода, которые мы и рассмотрим в этом посте.
1️⃣
toList()
С 25 по 27 ноября была серия постов о коллекторах (часть 1, часть 2, часть 3). Там я писала, что вместоcollect(Collectors.toList())было бы удобно писать просто
toList()30 ноября разработчик Oracle добавил метод toList() в класс Stream. Вряд ли он читает этот канал, но совпадение интересное🙂
Новый метод не совсем равнозначный:
▫️Collectors.toList() возвращает экземпляр ArrayList.
▫️Новый метод toList() возвращает неизменяемый список.
2️⃣ mapMulti
Это оптизированный flatMap. Объясню суть на примере. Заказ - класс Order, товар - класс Item. Заказ состоит из нескольких товаров. Из списка заказов хотим получить список всех товаров.
orders.stream()flatMap переводит "список списков" в один список. Товары для каждого заказа превращаются в Stream, а метод flatMap объединяет эти стримы в один.
.flatMap(order->order.getItems().stream())
.toList();
Минус: объект стрима создаётся всегда, даже для пустых списков.
mapMulti устраняет этот недостаток:
orders.stream()Что происходит:
.<Item>mapMulti((order, consumer) ->
order.getItems().forEach(item -> consumer.accept(item))
).toList();
mapMulti принимает на вход (order, consumer):
▪️order - элемент стрима, в нашем случае - заказ
▪️consumer - следующий этап в стриме. Наша задача - передать этому этапу все будущие элементы. Берём у заказа товары и для каждого вызываем consumer.accept(item).
Мультимэп не знает, для каких объектов будет вызван accept, и не может вывести тип выходных элементов. Поэтому для нормальной работы тип надо указать явно:
<Item>mapMulti(…)Когда использовать mapMulti?
✅ Небольшое количество элементов в списках.
Например, много заказов с 1-2 товарами
✅ Элементы легко получить без Stream API
Основная фишка mapMulti - нет промежуточных стримов. Если внутри метода создаётся стрим, то вся выгода сходит на нет.
❌ order.getItems().stream()…
Есть три вариации метода:
🔸IntStream mapMultiToInt
🔸LongStream mapMultiToLong
🔸DoubleStream mapMultiToDouble
Для них выходной тип не указывается.