I have been converting some code to use Java 8 features. In the following contrived example
Arrays.asList("1", "2", "3", "cheese", "5").stream().map(line -> {
try {
return Optional.of(Integer.parseInt(line));
} catch (NumberFormatException xep) {
return Optional.empty();
}
}).forEach( v ->
System.out.println(v.orElse(999))
);
(the intention is to parse some strings as ints and replace any unparseable values with 999)
The compiler reports
error: incompatible types: int cannot be converted to CAP#1
System.out.println(v.orElse(999))
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ? extends Object"
I've tried casting 999 to an Integer or Object with no success.
It seems that the real problem is that the inferred return type of the first lambda is Optional<Object>
and not Optional<Integer>
If I do this
Arrays.asList("1", "2", "3", "cheese", "5").stream().map(line -> {
Optional<Integer> ans;
try {
ans = Optional.of(Integer.parseInt(line));
} catch (NumberFormatException xep) {
ans = Optional.empty();
}
return ans;
}).forEach( v ->
System.out.println(v.orElse(999))
);
it works perfectly, but not quite as elegant. Is there a better way to 'guide' the compiler to the return type that I want?
A simple fix is to use a target type:
return Optional.<Integer> empty();
Also I note that you use Integer.parseInt
which returns an int
, so you could also use an OptionalInt
which will solve your problem and save a boxing operation:
try {
return OptionalInt.of(Integer.parseInt(line));
} catch (NumberFormatException xep) {
return OptionalInt.empty();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With