Строковые значения в Необязательном ofNullable - PullRequest
0 голосов
/ 23 января 2019

Представьте себе Optional.ofNullable проверку присвоения String:

String result = Optional.ofNullable(class1)
                .map(Class1::getClass2)
                .map(Class2::getResult);

Где getResult возвращает String.

Хотя я знаю, что это не компилируется, я могу исправить это, добавив toString() или .orElse(""); для сортировки.

В существующем состоянии ошибка:

Неверный тип возвращаемого значения в ссылке на метод, невозможно преобразовать java.lang.String до U

Я понимаю добавление orElse(""), поскольку это присвоит result пустому String.

Но какая польза от добавления toString(), если что-то будет null по пути? Или это просто для того, чтобы скомпилировать его?

Ответы [ 3 ]

0 голосов
/ 23 января 2019

Тип возвращаемого значения map равен Optional <U>, поэтому для получения реального значения необходимо вызвать orElse с типом возврата T.

Это реализация toString.если Optional:

@Override
public String toString() {
    return value != null
        ? String.format("Optional[%s]", value)
        : "Optional.empty";
}

Так, вызывая toString, вы никогда не получите реальное значение, но значение, обернутое в Optional, в то время как orElse вернет вам значение по умолчанию.

Посмотрим на разницу:

Integer i = 4;
String s = Optional.ofNullable(i)
         .map(Objects::toString)
         .toString();
System.out.println(s);

Вывод:

Optional[4]

С null:

Integer i = null;
String s = Optional.ofNullable(i)
          .map(Objects::toString)
          .toString();
System.out.println(s);

Вывод:

Optional.empty

При использовании orElse:

Integer i = null;
String s = Optional.ofNullable(i)
        .map(Objects::toString)
        .orElse("None");
System.out.println(s);

Вывод:

None

Таким образом, вы можете видеть, что эти методы имеют разные цели.

И ответ на ваш комментарий:

" Есть ли способ вызвать get (), а также вызвать orElse () в той же цепочке? "

Integer i = 10;
String s = Optional.ofNullable(i)
        .map(Objects::toString)
        .orElse("None");
System.out.println(s);

Вывод:

10

Вам не нужно явно вызывать get, значение будет извлечено, если не null;

/**
 * If a value is present, returns the value, otherwise returns
 * {@code other}.
 *
 * @param other the value to be returned, if no value is present.
 *        May be {@code null}.
 * @return the value, if present, otherwise {@code other}
 */
public T orElse(T other) {
    return value != null ? value : other;
}
0 голосов
/ 23 января 2019

Я понимаю добавление orElse (""), так как это присвоит результат пустому Строка.

Не похоже, что вы понимаете это для меня, потому что это не очень хорошее описание того, что происходит. Optional.orElse делает следующее: если необязательный параметр содержит значение, возвращает это значение. Если оно не содержит значения, верните любой аргумент, который вы ему дали.

Это семантически эквивалентно следующему:

if (optional.ifPresent())
{
    return optional.get();
}
else
{
    return theArgument;
}

Вызов toString, хотя он удовлетворит компилятор, это , а не , что вы хотите сделать. Вы конвертируете Optional объект сам в строку, не получая строку изнутри! Хотя ваша строка будет включена , это только из-за того, что разработчики JDK решили реализовать toString. Они также не могли бы обеспечить реализацию, оставив вам только поведение по умолчанию .

Вызов toString на Optional в принципе никогда не следует полагаться вне регистрации. По сути, это просто отладка информации. Если вы сделаете это, то также будет напечатана информация об обёртке Optional, что почти наверняка не то, что вам нужно.

System.out.println(Optional.empty());   // Optional.empty
System.out.println(Optional.of("foo")); // Optional[foo]
0 голосов
/ 23 января 2019

Если вы хотите, чтобы result было нулевым, если что-то по пути возвращает ноль, тогда выполните orElse(null)

String result = Optional.ofNullable(class1)
            .map(Class1::getClass2)
            .map(Class2::getResult).orElse(null);
...