Разработка программ. Мои заметки.

February 8, 2017 at 23:10

NullPointerException в Java. Сlass Optional в Java 9.

8. Что нового появится в классе Optional в Java 9.

У класса Optional появится три новых заметных метода:


    public void ifPresentOrElse( Consumer<? super T> action, Runnable emptyAction )
    public Optional<T> or( Supplier<? extends Optional<? extends T>> supplier );
    public Stream<T> stream();

Рассмотрим их детальнее.

Метод ifPresentOrElse()

Напомню, в Java 8 у класса Optional был метод ifPresent. Если Optional был непустой, то ifPresent вызывал переданную ему в параметре функцию, передавая ей значение, хранящееся в объекте Optional. А если пустой? ifPresent — ничего не делал.

Логичной представляется возможность вызвать некий другой метод, если наш Optional не содержит никакого значения. Этот метод ничего не получает в параметре. Просто вызывается в случае отсутствия значения в объекте Optional. Итак, метод ifPresentOrElse получает два метода в параметрах. Первый вызывается, если объект Optional имеет значение (этот метод получает это значение в параметре), второй — если значения у Optional нет. Метод не имеет параметров.

Выглядит вполне себе человечно:


    findUserWithLogin( userLogin )
        .ifPresentOrElse(
            this::displayUserProfile,
            this::proposeUserToRegister );
 

Метод or()

Несложный новый метод. Если у вас уже есть откуда-то полученный объект типа Optional, то вместо того, что бы проверять есть ли фактически в нём требуемое значение, вы можете вызвать or(), указав в нём метод, который будет вызван если ваш Optional никакого значения не содержит. Вызываемый метод должен возвращать значение типа Optional.

Таким образом, результатом вызова метода or() для некоторого Optional объекта будет либо этот же самый Optional объект, если он был непустой, либо другой Optional объект, который вернёт функция, переданная в параметре методу or(). Этот новый объект уже может быть и пустым.

Очевидно, что вы можете цепочкой вызывать метод or() передавая в параметре разные функции. Соответственно эта последовательность будет работать до первого найденного значения. Возвращается всегда объект Optional.


    Optional<User> user = findUser( userId )
    .or(() -> findUserInArchive( userId ); 

Метод stream()

Тут всё просто — Optional превращается в Stream. Если Optional хранил реальное значение, то будет Stream c одним значением. Если нет — будет пустой stream.

Автор — Владимир Рыбов