在lambdas上输入推断

Pet*_*ull 4 java-8

我一直在转换一些代码以使用Java 8功能.在以下人为的例子中

    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))
    );
Run Code Online (Sandbox Code Playgroud)

(目的是将一些字符串解析为整数并用999替换任何不可解析的值)

编译器报告

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"
Run Code Online (Sandbox Code Playgroud)

我已经尝试将999转换为Integer或Object但没有成功.

似乎真正的问题是第一个lambda的推断返回类型是Optional<Object>和不是Optional<Integer>

如果我这样做

    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))
    );
Run Code Online (Sandbox Code Playgroud)

它工作得很完美,但并不那么优雅.有没有更好的方法将编译器"引导"到我想要的返回类型?

ass*_*ias 5

一个简单的解决方法是使用目标类型:

return Optional.<Integer> empty();
Run Code Online (Sandbox Code Playgroud)

另外我注意到你使用Integer.parseInt哪个返回一个int,所以你也可以使用一个OptionalInt解决你的问题并保存一个拳击操作:

try {
  return OptionalInt.of(Integer.parseInt(line));
} catch (NumberFormatException xep) {
  return OptionalInt.empty();
}
Run Code Online (Sandbox Code Playgroud)