Java8 general puzzle

I am using Java 1.8.0_151, and there is code that does not compile, and I do not understand:

Optional optional = Optional.of("dummy"); Optional<Boolean> result1 = optional.map(obj -> true); // works fine boolean result2 = result1.orElse(false); // works fine boolean result3 = optional.map(obj -> true).orElse(false); // compilation error: Incompatible types: required boolean, found object Object result4 = optional.map(obj -> true).orElse(false); // works fine 

why does it work fine on result1 but gives a compilation error on result3 ?
Additional Information:

  • In the first line, when I change Optional to Optional<String> , result3 can also compile
  • When I split result3 into 2 lines: for example, result1 and result2 , result3 is able to compile
+7
java generics java-8 optional
source share
3 answers

Thank you for your responses. I just want to give detailed information on why it worked on resutl1 , but not result3 on:

 Optional<Boolean> result1 = optional.map(obj -> true); // works fine boolean result2 = result1.orElse(false); // works fine boolean result3 = optional.map(obj -> true).orElse(false); // compilation error: Incompatible types: required boolean, found object 

on result1 , the optional variable was raw, so optional.map(obj -> true) returned an optional raw type.

When I declared Optional<Boolean> result1 , the optional raw type was automatically cast to Optional<Boolean>
optional.map(obj -> true).orElse(false); failed because the optional object of the raw type cannot call .orElse(false)

Another example of this raw type behavior is:

 List li = new ArrayList<String>(); List<String> li1 = li; List<Integer> li2 = li; List<Map> li3 = li; li1.add("WWW"); li2.add(444); li3.add(new HashMap()); 

will work fine for all scripts, the li object will contain String, Integer and HashMap (). li1, li2, li3 was automatically added to the non-raw type.

0
source share

As soon as you lose type safety - it is lost for chain calls as-well. This is Optional<Object> != Optional . Therefore when you do

  Optional optional = Optional.of("dummy"); optional.map() 

map can only accept raw Function and nothing else, which, obviously, will return Object .

The correct way is to add type information:

 Optional<String> optional = Optional.of("dummy"); 

Or you can do it for a reason:

 boolean result3 = (boolean) optional.map(obj -> true).orElse(false) 
+8
source share

optional is raw optional , so optional.map(obj -> true) returns raw optional , and orElse(false) returns Object , not Boolean . The compiler does not know how to remove the Object field before the Boolean .

Changing

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

to

 Optional<Object> optional = Optional.of("dummy"); 

or

 Optional<String> optional = Optional.of("dummy"); 

you will overcome this error, as now optional.map(obj -> true) will return Optional<Boolean> and orElse(false) will return Boolean .

+4
source share

All Articles