was*_*ren 27 java generics lambda java-8 collectors
假设你有一个List数字.在该值List可以是类型的Integer,Double等等.当你声明这样的List有可能使用一个通配符(声明它?)或不用一个通配符.
final List<Number> numberList = Arrays.asList(1, 2, 3D);
final List<? extends Number> wildcardList = Arrays.asList(1, 2, 3D);
Run Code Online (Sandbox Code Playgroud)
所以,现在我想stream在List和collect它所有的Map使用Collectors.toMap(显然下面的代码只是为了说明问题的例子).让我们开始流式传输numberList:
final List<Number> numberList = Arrays.asList(1, 2, 3D, 4D);
numberList.stream().collect(Collectors.toMap(
// Here I can invoke "number.intValue()" - the object ("number") is treated as a Number
number -> Integer.valueOf(number.intValue()),
number -> number));
Run Code Online (Sandbox Code Playgroud)
但是,我不能对以下内容做同样的操作wildcardList:
final List<? extends Number> wildCardList = Arrays.asList(1, 2, 3D);
wildCardList.stream().collect(Collectors.toMap(
// Why is "number" treated as an Object and not a Number?
number -> Integer.valueOf(number.intValue()),
number -> number));
Run Code Online (Sandbox Code Playgroud)
编译器在调用时抱怨number.intValue()以下消息:
Test.java:找不到符号
符号:方法intValue()
位置:java.lang.Object类型的变量数
从编译器错误中可以看出number,lambda中的内容被视为a Object而不是a Number.
所以,现在问我的问题:
List,为什么它不像非通配符版本那样工作List?numberlambda中的变量被认为是Object而不是Number?aio*_*obe 36
这种类型推断并没有使它正确.如果明确提供type参数,它将按预期工作:
List<? extends Number> wildCardList = Arrays.asList(1, 2, 3D);
wildCardList.stream().collect(Collectors.<Number, Integer, Number>toMap(
number -> Integer.valueOf(number.intValue()),
number -> number));
Run Code Online (Sandbox Code Playgroud)
这是一个已知的javac错误:推断不应该将捕获变量映射到它们的上限.根据Maurizio Cimadamore的说法,
尝试修复然后因为它在8中破坏案例而退出,所以我们在8中做了一个更保守的修复而在9中完成了
显然还没有推出修复方案.(感谢 JoelBorggrén-Franck指出我正确的方向.)
| 归档时间: |
|
| 查看次数: |
20442 次 |
| 最近记录: |