Java 8 Lambda Chaining – Type Safety Enforcement

  • A+
Category:Languages

Snippet 1:

Optional.of(s).map(str -> str).orElse(""); 

Snippet 2:

Optional.of(s).map(str -> str).orElse(Optional.empty()); 

Snippet 3:

Optional.of(s).map(str -> Optional.of(str)).orElse("hello"); 

Snippet 1 is compiling fine but Snippet 2 & Snippet 3 compile with type incompatibility errors. While it's good that Snippet 2 & Snippet 3 fail, I do not understand how they are evaluated. In other words, I think I am missing some basics in terms of how the lambdas themselves are chained/invoked. Would appreciate if someone could help.

 


Snippet 1:

Optional.of(s).map(str -> str).orElse(""); 

Compiles because the default value provided to orElse is the same type as the value the Optional contains i.e. a String.

Snippet 2:

Optional.of(s).map(str -> str).orElse(Optional.empty()); 

does not compile because after map you have a Optional<String> but then you're providing a Optional<String> in the orElse whereas it should be a String.

Snippet 3:

Optional.of(s).map(str -> Optional.of(str)).orElse("hello"); 

does not compile because after map you have a Optional<Optional<String>> but you're passing a String in the orElse whereas it should be a Optional<String>.

To conclude orElse is declared as:

public T orElse(T other)

and documented as:

Returns the value if present, otherwise return other.

i.e. orElse basically says "give me the value the optional contains if present otherwise take the default value" as well as that T must be the same type as the value the Optional contains.

so if you have a Optional<String then you must supply a String to orElse, if you have a Optional<Integer then you must supply a Integer to orElse etc...

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: