作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
考虑以下代码片段:
public class JavaApplication4 {
static <T> List<T> functionConcat(List<T> l1, List<T> l2) {
return Stream.concat(l1.stream(), l2.stream()).collect(Collectors.toList());
}
// functionConcat in lambda form
static final BinaryOperator<List<? extends Number>> lambdaConcat = (l1, l2)
-> Stream.concat(l1.stream(), l2.stream()).collect(Collectors.toList());
public static void main(String[] args) {
// DOES NOT WORK with lambdaConcat
final List<Integer> x = new LinkedList<List<Integer>>()
.stream().reduce(new LinkedList<>(), lambdaConcat);
final List<Double> y = new LinkedList<List<Double>>()
.stream().reduce(new LinkedList<>(), lambdaConcat);
// WORKS with functionConcat
final List<Integer> x2 = new LinkedList<List<Integer>>()
.stream().reduce(new LinkedList<>(), JavaApplication4::functionConcat);
final List<Double> y2 = new LinkedList<List<Double>>()
.stream().reduce(new LinkedList<>(), JavaApplication4::functionConcat);
}
}
有没有办法修复lambdaConcat
这样 main()
中的两个对应语句变得正确了吗?
我尝试将类型表示为 BinaryOperator<List<Number>>
, BinaryOperator<List<?>>
, BinaryOperator<List<? extends Number>>
,甚至BinaryOperator<List>
,但是,可以理解的是,它们都不起作用。理想情况下,我想写lambdaConcat
带有类型参数 <T>
正如我在 functionConcat
中所做的那样,但我还没有找到用 lambda 表达式来表达这一点的方法。
最佳答案
这不起作用,因为 reduce()
操作的BinaryOperator<T>
是不变的:
T reduce(T identity, BinaryOperator<T> accumulator);
这本质上意味着如果您传递 List<Integer>
输入作为身份,您还必须传递 BinaryOperator<List<Integer>>
作为累加器,而不是 BinaryOperator<List<? extends Number>>
.
当使用方法引用时,或者两次内联 lambda 表达式时,您不会遇到此问题,因为 <T>
可以正确推断为List<Integer>
每一次。问题在于,您可以通过将 lambda 分配给固定类型来防止这种类型推断。相反,如果您编写了一个返回 lambda 的高阶泛型函数,它将再次工作:
static final <T extends Number> BinaryOperator<List<T>> lambdaConcat() {
return (l1, l2)->Stream.concat(l1.stream(), l2.stream()).collect(Collectors.toList());
}
您现在可以编写:
final List<Integer> x = new LinkedList<List<Integer>>()
.stream().reduce(new LinkedList<>(), lambdaConcat());
final List<Double> y = new LinkedList<List<Double>>()
.stream().reduce(new LinkedList<>(), lambdaConcat());
当然,在这一点上,方法引用解决方案可能还是更好。
关于java - 定义 lambda 表达式时使用泛型类型参数 <T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39014602/
我是一名优秀的程序员,十分优秀!