Фрагмент 1:
Optional.of(s).map(str -> str).orElse("");
Компилируется, поскольку значение по умолчанию, предоставленное для orElse
, того же типа, что и значение, которое Optional
содержит , т. Е.String
.
Фрагмент 2:
Optional.of(s).map(str -> str).orElse(Optional.empty());
не компилируется, потому что после map
у вас есть Optional<String>
, но затем вы предоставляете Optional<String>
в orElse
тогда как это должен быть String
.
Фрагмент 3:
Optional.of(s).map(str -> Optional.of(str)).orElse("hello");
не компилируется, потому что после map
у вас есть Optional<Optional<String>>
, но вы передаете String
в orElse
, тогда как это должно быть Optional<String>
.
В заключение orElse
объявляется как:
public T orElse (T other)
и задокументировано как:
Возвращает значение, если присутствует, в противном случае возвращает другое.
т.е. orElse
в основном говорит "дай мне значениефакультативно содержит, если присутствует, в противном случае принимает значение по умолчанию ", а также то, что T
должен быть того же типа, что и значение, которое содержит Optional
.
, поэтому, если у вас есть Optional<String
, вы должны указать String
до orElse
, если у вас есть Optional<Integer
, то вы должны указать Integer
до orElse
и т. Д.
С другой стороны, функция map
в вашем первом и втором примере фрагментов является излишней, и поэтому вы можете полностью ее опустить.
Всякий раз, когда вы видите, что вы сами вызываете Optional#map
с функцией v -> v
, это, вероятно, не нужно.