Метод findFirst()
используется в связке с filter()
для поиска первого элемента, соответствующего условию фильтрации.
var fruits = List.of("Apple", "Banana", "Apricot", "Orange", "Avocado");
var maybeFruit = fruits.stream()
.filter(s -> s.startsWith("A"))
.findFirst();
System.out.println(maybeFruit); // Optional[Apple]
Так как findFirst()
ищет ровно один элемент, то его результатом является одно значение, а не стрим. Но в отличие от свертки, где результат это то, что находится в аккумуляторе, в случае findFirst()
в качестве результата возвращается особый тип данных Optional
. Что это и зачем оно нужно?
По логике кажется, что возвратом должно быть либо конкретное значение если оно найдено, либо null
. Но в таком случае возникает необходимость постоянной проверки на наличие значения if (value != null)
. Главная проблема в том, что если забыть сделать ее проверку, компилятор ругаться не будет, null
является валидным значением для любых не примитивных типов. И такое постоянно происходит в тех местах, где возвратом может быть null
. Исключение NullPointerException
одно из самых распространенных в работающих программах на Java.
Чтобы этого не происходило в язык ввели тип Optional
. Это тип обертка, который хранит реальное значение внутри себя предоставляя к нему доступ через различные методы. Вот как выглядит работа с этим типом:
// Проверяем наличие значения внутри Optional с помощью isPresent()
if (maybeFruit.isPresent()) {
// Получаем значение через get()
System.out.println(maybeFruit.get()); // Apple
} else {
System.out.println("Ничего не нашли");
}
Все это работает потому, что отсутствие значения в Optional
не равно null
. Optional
создается следующим образом:
Optional.empty()
: создаетOptional
в случае если значение отсутствует.Optional.of(value)
: создаетOptional
сvalue
внутри.Optional.ofNullable(value)
: работает какempty()
если значениеnull
, иначе какof()
.
var optional = Optional.of("Hello");
Основные методы Optional
get()
: Возвращает значение если оно есть иначе выбрасывается исключениеNoSuchElementException
.isPresent()
: Возвращаетtrue
если значение представлено.orElse(defaultValue)
: Возвращает значение если оно есть иначе возвращаетсяdefaultValue
.orElseThrow(exceptionSupplier)
: Возвращает значение, если оно существует, иначе выбрасывает исключение, созданное внутриexceptionSupplier
.
var fruits = List.of("Apple", "Banana", "Apricot", "Orange", "Avocado");
var maybeFruit = fruits.stream()
.filter(s -> s.startsWith("C"))
.findFirst();
var fruit1 = maybeFruit.orElse("Strawberry"); // Strawberry
var fruit2 = maybeFruit.orElseThrow(() -> new RuntimeException("Fruit not found")); // Error
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.