1. Обзор
В этой статье мы преобразуем Optional‹T› в Collection. Необязательный может содержать 0 или 1 элемент. Если бы Optional был Collection, это была бы пустая коллекция или коллекция-одиночка.
Мы можем создать собственные методы, которые преобразуют Optional в Collection. Если значение присутствует в необязательных параметрах, мы вернем одноэлементную коллекцию, иначе вернем пустую коллекцию.
2. в список (необязательно‹T› opt)
Если значение присутствует в Optional, мы создаем SingletonList с этим значением, в противном случае мы возвращаем emptyList.
List<String> toList(Optional<String> optional) { return optional .map(Collections::singletonList) .orElseGet(Collections::emptyList); } List<String> list = toList(Optional.of("abc"))
3. toMap(Необязательно‹T› opt)
Если значение присутствует в Optional, мы создаем SingletonMap с этим значением, в противном случае мы возвращаем emptyMap. Возвращаемая Map будет иметь тот же ключ и значение.
import static java.util.Collections.*; Map<String, String> toMap(Optional<String> optional) { return optional .map(value -> singletonMap(value, value)) .orElseGet(Collections::emptyMap); } Map<String, String> map = toMap(Optional.of("abc"))
4. Собрать(Опционально‹T› opt, Коллектор‹T, A, R› коллектор)
Чтобы использовать существующий интерфейс для сбора данных в контейнер, мы можем использовать интерфейс Collector.
Это отличный способ сбора данных, поскольку мы можем передавать поведение нашего контейнера вместо того, чтобы писать собственные методы toList, toSet, toMap.
<A, T, R> R collect(Optional<T> optional, Collector<T, A, R> coll) { A a = coll.supplier().get(); optional.ifPresent(value -> coll.accumulator().accept(a, value)); return coll.finisher().apply(a); }
Вышеприведенный код принимает необязательный и сборщик в качестве параметра. Если значение существует в необязательном, оно добавляется в контейнер, иначе контейнер остается пустым.
- Получите изменяемый контейнер результатов от поставщика.
A accumulator = coll.supplier().get();
2. Если значение присутствует в необязательных параметрах, просто вставьте это значение в изменяемый контейнер результатов.
optional.ifPresent(value -> coll.accumulator().accept(a, value));
3. Преобразовать контейнер промежуточных результатов в контейнер результатов и вернуть его.
coll.finisher().apply(a)
Метод сбора с коллектором можно использовать несколькими способами.
Собрать в изменяемые контейнеры:
import static java.util.function.Function.identity; import static java.util.stream.Collectors.*; // To mutable List collect(optional, toList()); // To mutable Set collect(optional, toSet()); // To mutable Map collect(optional, toMap(identity(), identity()));
Возвращаемые коллекции являются изменяемыми, что означает, что вызывающая сторона этого API может повредить данные в коллекции. Для того, чтобы сделать эту коллекцию немодифицируемой, нам нужно использовать метод collectionAndThen класса Collectors.
Собрать в неизменяемые контейнеры:
import static java.util.function.Function.identity; import static java.util.stream.Collectors.*; // To unmodifiableList collect( optional, collectingAndThen( toList(), Collections::unmodifiableList)); // To unmodifiableSet collect( optional, collectingAndThen( toSet(), Collections::unmodifiableSet)); // To unmodifiableMap collect( optional, collectingAndThen( toMap(identity(), identity()), Collections::unmodifiableMap));
5. Заключение
В этой статье мы увидели, как можно преобразовать Optional в Collection с помощью интерфейса Collector.
Первоначально опубликовано на https://justamonad.com 4 октября 2019 г.