Обзор работы с опционалами (Optional Java)

Java Optional — представляет собой контейнер объект, который может или нет содержать не null значение. Если значение присутствует isPresent возвращает true в противном случае будет возвращено значение false и объект будет считаться пустым. 

Ранее мы мы писали о immutable объектах, которые также используются под капотом опционалов.

Инициализация java 8 optional

Опционал может быть инициализирован с помощью статического конструктора следующим образом

Optional<String> name = Optional.of("Java");
System.out.println(name); //output line: Optional[Java]

Если передать в подобный конструктор значение null возникнет java.lang.NullPointerException. Для безопасной передачи пустого значения можно воспользоваться методом ofNullable.

Изящная Java проверка на null (java null check).

В старом коде можно часто увидеть частые проверки на null, которые очень засоряют логику программы. Для улучшение качества кода мы рекомендуем использовать java optional. 

Рассмотрим простой пример:

Optional<String> version = Optional.ofNullable("Java 8");
if (version.isPresent()) {             //условие выполнится и мы увидим имя
   System.out.println(name.get()); //output John
}

В данном случае мы загружаем объект строку с версией языка программирования. Хотя значение может быть пустым.

Метод isPresent возвратит true если объект не пустой, что может помочь избежать лишних NPE исключений.

Для более продвинутой версии кода мы можем использовать лямбда выражение в методе ifPresent. В таком случае вся проверка сводиться к одной строчке.

Optional<String> version = Optional.ofNullable("Java 8");
version.ifPresent(e -> System.out.println(name.get()));

Что делать если объект пустой или Optional orElse обработка

Если объект оказался пустой в контейнере можно воспользоваться методами orElse или orElseGet

Optional<String> version = Optional.ofNullable("Java 8");
System.out.println(version.orElse("Java 9")); //output Java 8

Optional<Object> empty = Optional.empty();
System.out.println(empty.orElse("Java 9")); //output Java 9

Для более продвинутой версии можно воспользоваться опять таки лямбда выражениями:

Optional<String> version = Optional.ofNullable("Java 8");
System.out.println(version.orElseGet( () -> "Java 9")); //output Java 8

Optional<Object> empty = Optional.empty();
System.out.println(empty.orElseGet(() -> "Java 9")); //output Java 9

Модификация объекта с помощью служебных методов

map — метод модификации объекта в другой объект. Например:

String version = repository.findById(versionId)
  .map(version -> version.getCaption()).orElse("Java 8");

filter — производит выборку(фильтр) из искомого объекта. Например:

List<User> users = repository.findAll()
  .filter(user -> user.id != 0).orElse(new ArrayList());

flatMap — может конвертировать специфический поток в новый. Например список списков можно конвертировать в одиночный список.

Заключение

Использование контейнеров объектов упрощает работу с частыми проверками на пустое значение. Применяя лямбда выражение код можно сделать более изящным и безопасным.

Related posts

Leave a Comment