ПРИХОДИТЕ УЧИТЬСЯ НОВОЙ ПРОФЕССИИ ЛЕТОМ СО СКИДКОЙ ДО 70%Забронировать скидку
logo

Использование Java Optional: обработка NoSuchElementException

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Java
Скопировать код
String value = optionalString.orElseThrow(NoSuchElementException::new);

Для получения значения без предварительной проверки применяйте метод orElseThrow. Он генерирует исключение, если значение в Optional отсутствует.

От использования метода orElse(null) следует отказаться, если на то нет серьезных причин, так как он вновь вводит проверку на null, что противоречит основной идее Optional.

Раскрытие потенциала Optional

Элегантная работа с пустыми Optional

Optional является не усовершенствованным "null". Этот класс предоставляет набор инструментов, с помощью которых можно обеспечить корректную работу с отсутствующими значениями:

  • orElseThrow(): преобразует отсутствие значения в исключение.
  • ifPresent(): выполнит действие, если значение присутствует.
  • orElseGet(): получает значение из поставщика, если основного значения нет.

Преобразование значений с помощью map

Java
Скопировать код
String mappedValue = optionalString.map(String::toUpperCase).orElse("DEFAULT");

Метод map() пригодится для преобразования содержимого Optional с помощью функции с учётом выдачи альтернативного значения при его отсутствии.

Условное отсеивание значений через filter

Java
Скопировать код
Optional<String> filtered = optionalString.filter(s -> s.contains("expected"));

Для выполнения этого действия подходит метод filter().

Корректная работа с Optional в операциями Stream

Избегайте нерационального использования findFirst():

Java
Скопировать код
Optional<String> result = list.stream().filter( /* ваш критерий */ ).findFirst();
return result.orElse("default");

Обязательно обрабатывайте Optional, полученные при помощи findFirst(). Это позволит вывести значение по умолчанию или определить последующие действия.

Советы по работе с Optional

Использование orElse для указания значения по умолчанию

Java
Скопировать код
String defaultValue = optionalString.orElse("Default String"); // даже если null весьма нежелателен, превращаем его в "Default String"!

Используйте orElse чтобы установить альтернативное значение в случае отсутствия основного в Optional.

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

Java
Скопировать код
String computedDefault = optionalString.orElseGet(() -> computeDefault()); // Почему тратить ресурсы, когда есть возможность действовать эффективно?

Вариант orElseGet() особенно полезен за счет использования ленивых вычислений – функция поставщика активируется только при необходимости.

Избавьтесь от ошибок при распаковке

Помните старую поговорку – "семь раз отмерь, один раз отрежь". Используйте orElseThrow() вместо get(), чтобы избежать нежелательного появления исключения NoSuchElementException.

Визуализация

Визуализируйте Optional как сопутника на мосту:

Optional<String> safeCrossing = Optional.of("Sturdy Bridge"); Optional<String> riskyCrossing = Optional.empty();

Переход с проверкой if (safeCrossing.isPresent()) { // Мост есть, проходите спокойно 🌉🚶 } if (riskyCrossing.isPresent()) { // Моста нет, но вы проверили и остались в целости и сохранности 👀 }

Переход без проверки try { safeCrossing.get(); // мост есть, все в порядке 🚶 } catch (NoSuchElementException e) { // ...но помните: мосты не растут на каждом шагу! } try { riskyCrossing.get(); // вы не ожидали мост, и его действительно нет! } catch (NoSuchElementException e) { // Вот неудача! Моста нет, придется учиться плаванию 🏊‍♂️😱 }

Запомните принцип: "Семь раз отмерь, один – отрежь".

Будьте предусмотрительны: возвращайте Optional

Передавайте Optional дальше

Не всегда нужно извлекать значение из Optional самому:

Java
Скопировать код
public Optional<String> findTitle(String bookId) {
    return books.stream().filter(book -> book.hasId(bookId)).findFirst().map(Book::getTitle);
}

Оставьте решение о том, как обращаться с Optional, тому, кто вызывает ваш метод.

Optional и Stream: Идеальное сочетание

Java
Скопировать код
public Stream<String> titlesStream() {
    return books.stream().map(Book::getTitle);
}

Optional идеально работает в паре со Stream, предоставляя возможность тонкой обработки возможно отсутствующих значений в последовательностях.

Полезные материалы

  1. Optional (Java Platform SE 8) — Официальная документация Oracle по классу Java SE 8 Optional .
  2. 26 Reasons Why Using Optional Correctly Is Not Optional – Статья на DZone с рекомендациями по применению Optional.
  3. Optional – The Mother of All Bikesheds by Stuart Marks — Образовательное видео, объясняющее применение Optional в Java 8.