Поиск…


Вступление

Optional - это контейнерный объект, который может содержать или не содержать ненулевое значение. Если значение присутствует, isPresent() вернет true и get() вернет значение.

orElse() дополнительные методы, которые зависят от наличия содержащегося значения, например orElse() , который возвращает значение по умолчанию, если значение отсутствует, и ifPresent() который выполняет блок кода, если это значение присутствует.

Синтаксис

  • Необязательный.путь () // Создает пустой Необязательный экземпляр.
  • Необязательно. (Значение) // Возвращает необязательный параметр с указанным ненулевым значением. Исключение NullPointerException будет выбрано, если переданное значение равно null.
  • Необязательный.ofNullable (значение) // Возвращает необязательный параметр с указанным значением, которое может быть нулевым.

Возврат значения по умолчанию, если Необязательный пуст

Не используйте параметр Optional.get() поскольку это может NoSuchElementException . Способы Optional.orElse(T) и Optional.orElseGet(Supplier<? extends T>) обеспечивают способ предоставления значения по умолчанию в случае, если Опция пуста.

String value = "something";

return Optional.ofNullable(value).orElse("defaultValue");
// returns "something"

return Optional.ofNullable(value).orElseGet(() -> getDefaultValue());
// returns "something" (never calls the getDefaultValue() method)
String value = null;

return Optional.ofNullable(value).orElse("defaultValue");
// returns "defaultValue"

return Optional.ofNullable(value).orElseGet(() -> getDefaultValue());
// calls getDefaultValue() and returns its results

orElse различие между orElse и orElseGet заключается в том, что последнее оценивается только тогда, когда параметр Необязательный пуст, в то время как аргумент, предоставленный первому, оценивается, даже если опция не является пустой. Поэтому orElse следует использовать только для констант и никогда не предоставлять значение, основанное на каких-либо вычислениях.

карта

Используйте метод map() для параметра « Optional для работы со значениями, которые могут быть null без явных проверок null :

(Обратите внимание, что операции map() и filter() вычисляются сразу же, в отличие от их экземпляров Stream, которые оцениваются только при операции терминала .)

Синтаксис:

public <U> Optional<U> map(Function<? super T,? extends U> mapper)

Примеры кода:

String value = null;

return Optional.ofNullable(value).map(String::toUpperCase).orElse("NONE");
// returns "NONE"
String value = "something";

return Optional.ofNullable(value).map(String::toUpperCase).orElse("NONE");
// returns "SOMETHING"

Поскольку Option.map () возвращает пустую опцию, когда ее функция отображения возвращает значение null, вы можете связать несколько операций map () как форму нуль-безопасного разыменования. Это также известно как надежная цепочка .

Рассмотрим следующий пример:

String value = foo.getBar().getBaz().toString();

Любой из getBar , getBaz и toString потенциально может генерировать getBaz NullPointerException .

Вот альтернативный способ получить значение toString() используя Optional :

String value = Optional.ofNullable(foo)
                       .map(Foo::getBar)
                       .map(Bar::getBaz)
                       .map(Baz::toString)
                       .orElse("");

Это вернет пустую строку, если какая-либо из функций отображения вернет null.

Ниже приведен еще один пример, но немного другой. Он напечатает значение только в том случае, если ни одна из функций сопоставления не вернула значение null.

Optional.ofNullable(foo)
        .map(Foo::getBar)
        .map(Bar::getBaz)
        .map(Baz::toString)
        .ifPresent(System.out::println);

Выбросьте исключение, если нет значения

Используйте метод orElseThrow() Optional чтобы получить содержащееся значение или выбросить исключение, если оно не было установлено. Это похоже на вызов get() , за исключением того, что он допускает произвольные типы исключений. Метод берет поставщика, который должен вернуть исключение, которое нужно выбросить.

В первом примере метод просто возвращает содержащееся значение:

Optional optional = Optional.of("something");

return optional.orElseThrow(IllegalArgumentException::new);
// returns "something" string

Во втором примере метод генерирует исключение, потому что значение не задано:

Optional optional = Optional.empty();

return optional.orElseThrow(IllegalArgumentException::new);
// throws IllegalArgumentException

Вы также можете использовать синтаксис лямбда, если требуется выброс исключения с сообщением:

optional.orElseThrow(() -> new IllegalArgumentException("Illegal"));

Фильтр

filter() используется, чтобы указать, что вы хотите получить значение только в том случае, если оно соответствует вашему предикату.

Подумайте об этом, как if (!somePredicate(x)) { x = null; } .

Примеры кода:

String value = null;
Optional.ofNullable(value) // nothing
        .filter(x -> x.equals("cool string"))// this is never run since value is null
        .isPresent(); // false
String value = "cool string";
Optional.ofNullable(value) // something
        .filter(x -> x.equals("cool string"))// this is run and passes
        .isPresent(); // true
String value = "hot string";
Optional.ofNullable(value) // something
        .filter(x -> x.equals("cool string"))// this is run and fails
        .isPresent(); // false

Использование дополнительных контейнеров для примитивных типов номеров

OptionalDouble , OptionalInt и OptionalLong работают как Optional , но специально предназначены для переноса примитивных типов:

OptionalInt presentInt = OptionalInt.of(value);
OptionalInt absentInt = OptionalInt.empty();

Поскольку числовые типы имеют значение, для null нет специальной обработки. Пустые контейнеры можно проверить с помощью:

presentInt.isPresent(); // Is true.
absentInt.isPresent(); // Is false.

Точно так же существуют сокращения для управления стоимостью:

// Prints the value since it is provided on creation.
presentInt.ifPresent(System.out::println);

// Gives the other value as the original Optional is empty.
int finalValue = absentInt.orElseGet(this::otherValue);

// Will throw a NoSuchElementException.
int nonexistentValue = absentInt.getAsInt();

Выполнить код, только если имеется значение

Optional<String> optionalWithValue = Optional.of("foo");
optionalWithValue.ifPresent(System.out::println);//Prints "foo".

Optional<String> emptyOptional = Optional.empty();
emptyOptional.ifPresent(System.out::println);//Does nothing.

Ленько предоставлять значение по умолчанию с помощью поставщика

Нормальный orElse метод принимает Object , так что вы могли бы задаться вопросом, почему есть возможность предоставить Supplier здесь ( orElseGet метод).

Рассматривать:

String value = "something";
return Optional.ofNullable(value)
               .orElse(getValueThatIsHardToCalculate()); // returns "something"

Он все равно вызовет getValueThatIsHardToCalculate() хотя результат не используется, поскольку необязательный не пуст.

Чтобы избежать этого наказания, вы предоставляете поставщика:

String value = "something";
return Optional.ofNullable(value)
               .orElseGet(() -> getValueThatIsHardToCalculate()); // returns "something"

Таким образом getValueThatIsHardToCalculate() будет вызываться только в том случае, если параметр Optional пуст.

FlatMap

flatMap похож на map . Разница описывается javadoc следующим образом:

Этот метод похож на map(Function) , но предоставленный сопоставитель - это тот, результат которого уже является Optional , и если вызывается, flatMap не обертывает его дополнительным Optional .

Другими словами, когда вы связываете вызов метода, который возвращает Optional , использование Optional.flatMap позволяет избежать создания вложенных Optionals .

Например, учитывая следующие классы:

public class Foo {
    Optional<Bar> getBar(){
        return Optional.of(new Bar());
    }
}

public class Bar {
}

Если вы используете Optional.map , вы получите вложенный Optional ; т.е. Optional<Optional<Bar>> .

Optional<Optional<Bar>> nestedOptionalBar =
    Optional.of(new Foo())
        .map(Foo::getBar);

Однако, если вы используете Optional.flatMap , вы получите простой Optional ; т.е. Optional<Bar> .

Optional<Bar> optionalBar =
    Optional.of(new Foo())
        .flatMap(Foo::getBar);


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow