Как я могу передать функцию сравнения в метод Java? - PullRequest
0 голосов
/ 03 мая 2019

Я портирую некоторый код с Python на Java 8 и застрял в методе, где один из параметров является матрицей, а другие - функцией сравнения, которая в Python похожа на np.gt или np.lt.

Мне трудно реализовать это на Java, поскольку сравнения Java (Comparator) работают только со сложными типами, а автобокс не работает.

Что я хотел бызапись:

public static boolean[][] matrix_check(double[][] matrix, Comparator<double> comparator) {
    // ...
}

Но Comparator<double>, очевидно, не работает.Как мне реализовать эту функциональность в Java?

Ответы [ 3 ]

2 голосов
/ 03 мая 2019

Наличие определенного метода с Comparator в качестве одного из формальных параметров означает, что вы можете передать в него лямбда-выражение функционального интерфейса, соответствующего Comparator. Не забудьте обернуть Comparator вокруг упакованных типов, так как вы не можете использовать примитивные.

Важнейшим является Comparator::compare, который возвращает int и, следовательно, ведет себя как BiFunction<T, T, Integer>, должен быть сокращен как лямбда-выражение (или ссылка на метод в некоторых случаях):

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

Лямбда-выражение может также передаваться напрямую:

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

В приведенном выше примере вы должны учитывать точность, потерянную при приведении к int. double не подходят для объяснения лямбда-выражения. Для целых чисел или объектов, реализующих 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 голосов
/ 03 мая 2019

Обобщения Java не поддерживают примитивные типы. Вы должны передать Comparator<Double> вместо этого. Вы можете сравнить значения double и Double с таким компаратором. Сравнение значений double позволит использовать автобокс.

0 голосов
/ 06 мая 2019

Я использовал 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.
 }
...