如何将比较函数传递给Java方法?

时间:2019-05-03 20:32:54

标签: java lambda java-8 functional-programming comparator

我正在将一些代码从Python移植到Java 8,并停留在一种方法上,其中一个参数是矩阵,而另一个参数是比较函数,在Python中类似于np.gt或{{ 1}}。

我发现这很难用Java实现,因为Java比较器(Comparator)仅对复杂类型起作用,而自动装箱似乎不起作用。

我想写的是:

np.lt

但是public static boolean[][] matrix_check(double[][] matrix, Comparator<double> comparator) { // ... } 显然不起作用。我应该如何在Java中实现此功能?

3 个答案:

答案 0 :(得分:2)

Java泛型不支持基本类型。 您需要改为传递Comparator<Double>。 您可以使用这样的比较器比较doubleDouble的值。比较double值将利用自动装箱。

答案 1 :(得分:2)

使用Comparator作为形式参数之一的已定义方法意味着您可以在其中传递与Comparator相对应的功能接口的lambda表达式。不要忘记将Comparator包装在盒装类型周围,因为您不能使用原始类型。

关键是Comparator::compare,它返回int,因此其行为类似于BiFunction<T, T, Integer>,应缩短为lambda表达式(某些情况下为方法引用):

double[][] doubleArray = ...
Comparator<Double> comparator = (left, right) -> (int)(left - right);  
boolean[][] booleanArray = matrix_check(doubleArray, comparator);

lambda表达式也可以直接传递:

double[][] newDoubleArray = matrix_check(doubleArray, (int)(left - right));

在上面的示例中,您必须注意由于强制转换为int而导致的精度损失。 double不适合lambda表达式解释。对于实现Comparable的整数或对象,整个过程会容易得多:

Comparator<Integer>  c1 = (l, r) -> l- r;           // l - r results in int
Comparator<String>   c2 = (l, r) -> l.compareTo(r); // implements Comparable by default
Comparator<MyObject> c3 = (l, r) -> l.compareTo(r); // must implement Comparable 

答案 2 :(得分:0)

我最终使用了DoubleBinaryOperator

DoubleBinaryOperator lt = (x, y) -> { if (x > y) return 1; else return -1; };
DoubleBinaryOperator gt = (x, y) -> { if (x < y) return 1; else return -1; };

其他二进制操作很容易添加。

方法定义和比较器用法如下:

public static Boolean[][] matrix_check(double[][] matrix, DoubleBinaryOperator comparator) {
  if (comparator.applyAsDouble(arg1, arg2) > 0) {
    // Logic if true.
  } else {
    // Logic if false.
 }