Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否可以使用可选参数创建通用功能接口?_Java_Generics_Interface_Java 11 - Fatal编程技术网

Java 是否可以使用可选参数创建通用功能接口?

Java 是否可以使用可选参数创建通用功能接口?,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) {

我试图用一个方法(当然)在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) {
    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