gpt4 book ai didi

java - 定义 lambda 表达式时使用泛型类型参数

转载 作者:行者123 更新时间:2023-11-30 06:08:57 25 4
gpt4 key购买 nike

考虑以下代码片段:

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com