Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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_Oop_Generics - Fatal编程技术网

Java中的泛型解释向量方法应该接受任何类型

Java中的泛型解释向量方法应该接受任何类型,java,oop,generics,Java,Oop,Generics,在我学习java时,我正在遵循编写接口代码的实践。我有一个函数接口,它有一个executeFunction()方法。但是我想让这个方法变得通用。因此,客户机可以传入字符串、布尔值、整数、double等的列表,以便对它们运行聚合计算 但是我对泛型没有很好的理解,所以我想要一些建议和解释,说明我在编码过程中的设计方法实际上能够做什么。我想有一个StatsFunctions和算术函数的具体实现类,可以注入到其他类中使用它们的函数。(有点尝试策略模式) 这是我的密码: import java.util.

在我学习java时,我正在遵循编写接口代码的实践。我有一个
函数
接口,它有一个executeFunction()方法。但是我想让这个方法变得通用。因此,客户机可以传入字符串、布尔值、整数、double等的列表,以便对它们运行聚合计算

但是我对泛型没有很好的理解,所以我想要一些建议和解释,说明我在编码过程中的设计方法实际上能够做什么。我想有一个StatsFunctions和算术函数的具体实现类,可以注入到其他类中使用它们的函数。(有点尝试策略模式)

这是我的密码:

import java.util.List;

public interface Function {

    public <T> double executeFunction(List<T> vector);

}
提前感谢。

公共界面功能{
public interface Function<T> {
  public T executeFunction(List<T> vector);
}
公共T执行函数(列表向量); }
改为: T型公共接口函数

这就是为什么函数
executeFunction
返回您上面声明的类型T

请注意,T始终是一个对象,但Java可以通过自动装箱处理基本类型(int、double)。

更好的是:

public interface Function<F, T> {
    T apply(F input);
}
实施情况如下:

public class ArithmeticFunction implements MyFunction {

    public double executeFunction(List vector) {
        double retVal = 0;
        for (int i = 0; i < vector.size(); i++) {
            retVal += (((Double)vector.get(i))).doubleValue();
        }
        return retVal;
    }
}
但是,这也是可能的,并将在运行时为您提供ClassCastException::

// Bad !!
af.executeFunction(new ArrayList(Arrays.asList(new String[] {"A", "B", "C"})));
因此,总结一下,在实现之间进行比较(并了解运行时发生的情况)::

//不编译
公共类算术函数实现MyFunction{
公共双执行函数(列表向量){
int-retVal=0;
对于(int i=0;i
以及上面给出的示例

哦,要解决您的问题,您必须:

public interface Function<T> {

    public double executeFunction(List<T> vector);
}
公共接口功能{
公共双执行函数(列表向量);
}

我知道这里介绍的一些概念可能还不清楚,所以你最好的办法是使用泛型教程来提高速度。

TL;DR:
放在方法上意味着调用该方法时将知道列表的实际类型<接口上的代码>
表示声明类时列表的类型是已知的

本声明

public interface Function {
    public <T> double executeFunction(List<T> vector);
}
您可以通过以下方式声明类:

public class Summation implements Function<Double> {
    public double executeFunction(List<Double> vector) {
        // ...        
    }
}
公共类求和实现函数{
公共双执行函数(列表向量){
// ...        
}
}

现在您可以确定
vector
中的每个元素都是一个
Double
,因此您可以安全地将它们相加。

这很好,假设函数将返回与输入类型相同的结果——情况并非总是如此。例如,某些函数返回布尔值,而与输入类型无关。虽然这不是确切的技术术语,也许将其称为“AggregateFunction”可能有助于说明它的用途?我不确定将
double
替换为
T
作为返回类型是否正确。请注意,将有一个
算术函数
类实现。在您可能实现的任何算术代码中,返回值很可能与输入的类型相同。但是,您可以将其定义为函数来定义返回值,但在某些情况下,它变得太复杂,无法实际使用。例如,为什么在接口声明中使用T?如果我不申报呢?如果我这样做呢?请在这里进行一些知识传授。我不在乎自动装箱。谢谢。泛型说的不是“我使用double类型的变量编写函数”,而是“我使用T类型的变量编写函数”,然后定义T的实际类型。它是一种类型的变量。您可以为这些变量指定任何您想要的名称(T是最常见的名称),并且可以在通常编写变量类型的任何位置使用该占位符。在运行时,JIT会将占位符替换为要使用的实际类型。我不确定您是否真的需要泛型。你能给出你想使用的客户端代码的例子吗?假设类/方法可以做任何你想做的事情
ArithmeticFunction af = new ArithmeticFunction();
// Good
af.executeFunction(new ArrayList(Arrays.asList(new Double[] {new Double(1), new Double(2)})));
// Bad !!
af.executeFunction(new ArrayList(Arrays.asList(new String[] {"A", "B", "C"})));
// does not compile
public class ArithmeticFunction implements MyFunction {

    public double executeFunction(List<Integer> vector) {
        int retVal = 0;
        for (int i = 0; i < vector.size(); i++) {
            retVal = vector.get(i) + retVal;
        }
        return retVal;
    }
}
public interface Function<T> {

    public double executeFunction(List<T> vector);
}
public interface Function {
    public <T> double executeFunction(List<T> vector);
}
public interface Function<T> {
    public double executeFunction(List<T> vector);
}
public class Summation implements Function<Double> {
    public double executeFunction(List<Double> vector) {
        // ...        
    }
}