如何从 Class 中获取二元运算符?

How can I get a Binary Operator from a Class?

有没有办法获得与 class 相关的二元运算符? 我有这个方法有两个参数:

    public <T extends Number> T[] sumArray(T[] arrayToAdd, BinaryOperator<T> add){
        T[] arrayToReturn =  arrayToAdd.clone();
        for (int i = 0; i < arrayToAdd.length; i++) {
            arrayToReturn[i] = arrayToAdd[i];
            for (int j = 0; j < i; j++) {
                arrayToReturn[i] = add.apply(arrayToReturn[i], arrayToAdd[j]);
            }
        }
        return arrayToReturn;
    }

但是,我想做这样的事情:

    public <T extends Number> T[] sumArray(T[] arrayToAdd){
        BinaryOperator add = arrayToAdd.getClass().getBinaryOperator(sum);
        T[] arrayToReturn =  arrayToAdd.clone();
        for (int i = 0; i < arrayToAdd.length; i++) {
            arrayToReturn[i] = arrayToAdd[i];
            for (int j = 0; j < i; j++) {
                arrayToReturn[i] = add.apply(arrayToReturn[i], arrayToAdd[j]);
            }
        }
        return arrayToReturn;
    }

PD:当从另一个 class 调用第一种方法时,我也遇到了问题: api.sumArray(intArray, Integer::sum); 错误说:'Object is not convertible to int'

----------------编辑----------------

最小可重现示例

public class guide6Main<T extends Comparable<T>, N extends Number> {
    public static void main(String[] args) {
        ApiArray api = new ApiArray();
        Integer[] intArray = {1, 2, 3, 4};
        api.exercise6(intArray, Integer::sum);
     }
}
public class ApiArray<T extends Comparable<T>, N extends Number> {
    public  <N extends Number> N[] exercise6(N[] arrayToAdd, BinaryOperator<N> add){
        N[] arrayToReturn =  arrayToAdd.clone();
        for (int i = 0; i < arrayToAdd.length; i++) {
            arrayToReturn[i] = arrayToAdd[i];
            for (int j = 0; j < i; j++) {
                arrayToReturn[i] =add.apply(arrayToReturn[i],arrayToAdd[j] );
            }
        }
        return arrayToReturn;
    }
}

这是错误:

D:\Documentos\Austral\Álgerba III\src\Guia6\Team2Solution\guide6Main.java:11:49
java: incompatible types: invalid method reference
    incompatible types: java.lang.Object cannot be converted to int

P.D.2:此外,arrayToAdd 不能包含多种类型,我的意思是,它可以,但在这种情况下不能 (最小可重现的例子可以吗?我从来没有做过那样的事)

您的 class 设计在这一点上不是最优的。 您的方法隐藏了 N 的 class 参数。

所以当你这样做时

ApiArray api = new ApiArray();
Integer[] intArray = {1, 2, 3, 4};
api.exercise6(intArray, Integer::sum);

您正在使用原始类型(请参阅 ApiArray api 而不提供类型)这将导致 N 只是 object因为 N 此时未绑定到任何类型。这将导致 N 被擦除为 Object 因为 Object 是最不超类型。

因此,在实例化 ApiArray class 时,您需要为 TN 提供通用类型 - 例如:

 ApiArray<Integer, Integer> api = new ApiArray();
 Integer[] intArray = {1, 2, 3, 4};
 api.exercise6(intArray, Integer::sum );

另一种实现结果的方法是删除 class:

的泛型类型边界
class ApiArray {
    public  <N extends Number> N[] exercise6(N[] arrayToAdd, BinaryOperator<N> add){
        N[] arrayToReturn =  arrayToAdd.clone();
        for (int i = 0; i < arrayToAdd.length; i++) {
            arrayToReturn[i] = arrayToAdd[i];
            for (int j = 0; j < i; j++) {
                arrayToReturn[i] =add.apply(arrayToReturn[i],arrayToAdd[j] );
            }
        }
        return arrayToReturn;
    }
}

此处泛型类型/边界由方法签名提供。


另一种方法是从您的方法中删除通用类型参数并使用 class 本身的通用类型参数范围:

class ApiArray<T extends Comparable<T>, N extends Number> {
public N[] exercise6(N[] arrayToAdd, BinaryOperator<N> add){
    N[] arrayToReturn =  arrayToAdd.clone();
    for (int i = 0; i < arrayToAdd.length; i++) {
        arrayToReturn[i] = arrayToAdd[i];
        for (int j = 0; j < i; j++) {
            arrayToReturn[i] =add.apply(arrayToReturn[i],arrayToAdd[j] );
        }
    }
    return arrayToReturn;
}
}


  ApiArray<Integer, Integer> api = new ApiArray();
        Integer[] intArray = {1, 2, 3, 4};
        api.exercise6(intArray, Integer::sum );

纯粹是关于错误“incompatible types: java.lang.Object cannot be converted to int”的回答:

public class guide6Main<T extends Comparable<T>, N extends Number> {
    public static void main(String[] args) {
        ApiArray api = new ApiArray();
        Integer[] intArray = {1, 2, 3, 4};
        api.exercise6(intArray, Integer::sum);
     }
}

public class ApiArray<T extends Comparable<T>, N extends Number> {
    public  <N extends Number> N[] exercise6(N[] arrayToAdd, BinaryOperator<N> add){
        // ...
    }
}

ApiArray 是泛型类型,但 ApiArray api 是原始类型变量(它没有类型参数)。

原始类型会清除所有泛型,即使是那些与省略的类型参数无关的泛型。

使用通配符类型声明api

    ApiArray<?, ?> api = new ApiArray<>();

(或者,很明显,如果有可以添加的类型,则将非通配符类型放在那里)。

如果不需要,请从 class 中删除类型参数。