Java 是否可以使用可选参数创建通用功能接口?
我试图用一个方法(当然)在Java中创建一个函数接口,该方法可以接受任何类型的参数并返回任何数据类型(即泛型方法) 这就是我到目前为止所做的: Calculator.javaJava 是否可以使用可选参数创建通用功能接口?,java,generics,interface,java-11,Java,Generics,Interface,Java 11,我试图用一个方法(当然)在Java中创建一个函数接口,该方法可以接受任何类型的参数并返回任何数据类型(即泛型方法) 这就是我到目前为止所做的: Calculator.java public interface Calculator<T> { T operation(T n1, T... n2); //this is where the optional parameter comes in } public static void main(String[] args) {
public interface Calculator<T> {
T operation(T n1, T... n2); //this is where the optional parameter comes in
}
public static void main(String[] args) {
Calculator<Integer> addition = (n1, n2) -> n1 + n2; //this gives an error
}
公共接口计算器{
T操作(T n1,T…n2);//这是可选参数的所在
}
Main.java
public interface Calculator<T> {
T operation(T n1, T... n2); //this is where the optional parameter comes in
}
public static void main(String[] args) {
Calculator<Integer> addition = (n1, n2) -> n1 + n2; //this gives an error
}
publicstaticvoidmain(字符串[]args){
计算器加法=(n1,n2)->n1+n2;//这会给出一个错误
}
错误显示:
二进制运算符“+”的操作数类型错误
- 是否可以在Java中创建带有可选参数的通用函数接口
- 如果是,我做错了什么
+
如果要保留相同的界面,则需要将主界面中的代码更改为:
public static void main(String[] args) {
Calculator<Integer> addition = (n1, n2) -> n1 + Arrays.stream(n2).reduce(0, Integer::sum);
}
一个运行示例:
public class Main {
public static void main(String[] args) {
Calculator<Integer> addition = n -> (n == null) ? 0 : Arrays.stream(n).reduce(0, Integer::sum);
System.out.println(addition.operation(1, 2));
System.out.println(addition.operation(1));
System.out.println(addition.operation());
System.out.println(addition.operation(null));
}
}
这样可以很好地工作,因为您将对两个整数应用运算符+
如果要保留相同的界面,则需要将主界面中的代码更改为:
public static void main(String[] args) {
Calculator<Integer> addition = (n1, n2) -> n1 + Arrays.stream(n2).reduce(0, Integer::sum);
}
一个运行示例:
public class Main {
public static void main(String[] args) {
Calculator<Integer> addition = n -> (n == null) ? 0 : Arrays.stream(n).reduce(0, Integer::sum);
System.out.println(addition.operation(1, 2));
System.out.println(addition.operation(1));
System.out.println(addition.operation());
System.out.println(addition.operation(null));
}
}
如中所示,您可以通过lambda表达式处理varargs参数来实现接口,例如使用流。但是,除了两个参数版本外,您还可以为关联操作设计一个接口,提供默认方法:
接口计算器{
T操作(T n1,T n2);
默认T操作(T优先,T…参数){
返回Stream.concat(Stream.of(第一个)、Arrays.Stream(args))
.reduce(this::operation).orelsetrow();
}
}
请注意,方法签名操作(T first,T…args)
强制至少有一个元素,它允许使用reduce
,而无需标识元素或空流的回退值
你可以像这样使用它
计算器加法=(n1,n2)->n1+n2;
整数和=加法运算(1,2,3,4);
但操作必须是关联的,如加法、乘法或字符串串联等。如果要支持非关联操作,这些操作必须使用适当的实现重写操作(T first,T…args)
。重写它不适用于lambda表达式。另一种选择是为任意计算提供接口,并为关联操作提供专门化:
接口计算器{
T操作(T优先,T…args);
}
接口AssociateVop扩展计算器{
T操作(T n1,T n2);
@凌驾
默认T操作(T优先,T…参数){
返回Stream.concat(Stream.of(第一个)、Arrays.Stream(args))
.reduce(this::operation).orelsetrow();
}
}
然后,非关联操作可以通过处理所有参数的lambda表达式实现计算器
,而关联操作可以实现如下:
Calculator addition=(associateveop)(n1,n2)->n1+n2;
类型转换的必要性可以通过工厂方法消除,对其参数使用类型推断。然而,当我们在这一点上,我们可以记住,已经有一个函数接口类型的操作与两个参数的例子,甚至使用隐式。因此,另一种选择是:
接口计算器{
T操作(T优先,T…args);
静态计算器关联(二进制运算符op){
return(first,other)->Stream.concat(Stream.of(first),Arrays.Stream(other))
.reduce(op.orelsetrow();
}
}
这仍然允许通过lambda表达式进行任意实现,而关联操作可以通过简化的:
Calculator addition=Calculator.associative((n1,n2)->n1+n2);
(或Calculator.associative(Integer::sum)
)如中所示,您可以通过lambda表达式处理varargs参数来实现接口,例如使用流。但是,除了两个参数版本外,您还可以为关联操作设计一个接口,提供默认方法:
接口计算器{
T操作(T n1,T n2);
默认T操作(T优先,T…参数){
返回Stream.concat(Stream.of(第一个)、Arrays.Stream(args))
.reduce(this::operation).orelsetrow();
}
}
请注意,方法签名操作(T first,T…args)
强制至少有一个元素,它允许使用reduce
,而无需标识元素或空流的回退值
你可以像这样使用它
计算器加法=(n1,n2)->n1+n2;
整数和=加法运算(1,2,3,4);
但操作必须是关联的,如加法、乘法或字符串串联等。如果要支持非关联操作,这些操作必须使用适当的实现重写操作(T first,T…args)
。重写它不适用于lambda表达式。另一种选择是为任意计算提供接口,并为关联操作提供专门化:
接口计算器{
T操作(T优先,T…args);
}
接口AssociateVop扩展计算器{
T操作(T n1,T n2);
@凌驾
默认T操作(T优先,T…参数){
返回Stream.concat(Stream.of(第一个)、Arrays.Stream(args))
.reduce(this::operation).orelsetrow();
}
}
然后,非关联操作可以通过处理所有参数的lambda表达式实现计算器
,而关联操作可以实现如下:
Calculator addition=(associateveop)(n1,n2)->n1+n2;
有必要举行一次会议
3 // 1 + 2
1 // 1
0 // empty array
0 // null