Получить доступ

Optional: явное отсутствие значения

Зачем Optional, orElse против orElseGet, композиция map/flatMap/filter и антипаттерны использования.

Зачем Optional

Optional<T> — контейнер, который либо содержит значение, либо пуст. Его смысл — сделать «значения может не быть» ЯВНЫМ в типе возвращаемого значения, чтобы вызывающий не забыл про этот случай, как это происходит с молчаливым null.

Главное применение — тип результата методов, которые могут не найти значение (findById, findFirst). Это не универсальная замена null везде.

Создание и распаковка

Создают через Optional.of(x) (x не null, иначе NPE), Optional.ofNullable(maybeNull) и Optional.empty(). Достают значение безопасно: orElse(default), orElseGet(supplier), orElseThrow(), ifPresent(consumer), ifPresentOrElse.

Ключевая ловушка — orElse против orElseGet: аргумент orElse(expr) вычисляется ВСЕГДА, даже если Optional не пуст; orElseGet(() -> expr) вызывает поставщик ТОЛЬКО когда значения нет. Если дефолт дорогой или с побочным эффектом (запрос в БД, new) — это разница между лишней работой и ленивым вычислением.

// orElse всегда выполнит expensiveDefault(), даже если value присутствует:
String a = opt.orElse(expensiveDefault());
// orElseGet выполнит лишь при пустом opt:
String b = opt.orElseGet(() -> expensiveDefault());

Композиция

Optional поддерживает map (преобразовать значение, если есть), flatMap (когда функция сама возвращает Optional — разворачивает Optional<Optional<>>), filter (оставить, если подходит). Это позволяет строить цепочки без ручных проверок на null.

Например: findUser(id).map(User::address).map(Address::city).orElse("unknown") — безопасный путь сквозь возможные пропуски.

Антипаттерны

opt.get() без проверки — почти всегда ошибка (бросит NoSuchElementException); вместо isPresent()+get() используют map/orElse/ifPresent. Optional как ПОЛЕ класса или ПАРАМЕТР метода — антипаттерн (он не Serializable, добавляет обёртку и аллокацию; для полей берут обычный nullable + контроль доступа, для параметров — перегрузку или nullable).

Не возвращайте Optional<Collection> — верните пустую коллекцию (пустота уже выражает «ничего нет»). И не оборачивайте в Optional то, что не бывает пустым.

Как отвечать на собеседовании

Объясните цель Optional (явное отсутствие в типе результата, против тихого null), разберите orElse vs orElseGet (orElse вычисляет всегда — ленивость важна для дорогих дефолтов), покажите композицию map/flatMap/filter и назовите антипаттерны (get без проверки, Optional как поле/параметр, Optional<Collection>).

Вопросы по теме

Читайте также

Закрытая бета

Знать тему — половина дела

На живом собеседовании sotto слышит вопрос интервьюера и показывает короткий ответ и план. Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем