Fragmento 1:
Optional.of(s).map(str -> str).orElse("");
Fragmento 2:
Optional.of(s).map(str -> str).orElse(Optional.empty());
Fragmento 3:
Optional.of(s).map(str -> Optional.of(str)).orElse("hello");
Snippet 1
está bien, pero la compilación Snippet 2
y Snippet 3
compilación de errores tipo de incompatibilidad. Si bien es bueno que Snippet 2
y Snippet 3
fallar, no entiendo como son evaluados. En otras palabras, creo que me faltan algunos conceptos básicos en términos de cómo los propios lambdas están encadenados / invocado. Agradecería si alguien puede ayudar.
Fragmento 1:
Optional.of(s).map(str -> str).orElse("");
Compila porque el valor predeterminado proporcionado a es del mismo tipo como el valor de la contiene es decir, una .orElse
Optional
String
Fragmento 2:
Optional.of(s).map(str -> str).orElse(Optional.empty());
no se compila porque después map
usted tiene un Optional<String>
pero entonces usted está proporcionando una Optional<String>
en el orElse
mientras que debería ser una String
.
Fragmento 3:
Optional.of(s).map(str -> Optional.of(str)).orElse("hello");
no se compila porque después map
usted tiene un Optional<Optional<String>>
pero estás pasando una String
en la orElse
que es conveniente prever una Optional<String>
.
Para concluir orElse
está declarada como:
T pública OrElse (T otra)
y documentado como:
Devuelve el valor si está presente, de lo contrario devuelve otros.
es decir, orElse
básicamente dice "dame el valor opcional contiene si está presente lo contrario toma el valor por defecto", así como que T
deben ser del mismo tipo que el valor de la Optional
contiene.
por lo que si usted tiene un Optional<String
entonces usted debe suministrar una String
a orElse
, si tiene un Optional<Integer
entonces usted debe suministrar una Integer
a orElse
etc ...
Por otro lado, la map
función en su primera y segunda ejemplo fragmentos son superfluas y puede, por lo tanto, omitir por completo.
Cada vez que vea a su propia vocación Optional#map
con la función que v -> v
es probable que no sea necesario.