Прохождение универсальную функцию в качестве параметра


Столкнулся с этим идея и мне интересно, если это возможно.

Я пытаюсь сделать одну функцию, которая может проверить все мои алгоритмы сортировки динамически. Я хочу быть в состоянии передать функцию сортировки в качестве параметра и алгоритм будет использовать функцию сортировки с его собственных динамических параметров. Это пример того, что я пытаюсь сделать:

class manyFunctions{
    int[] mergeSort(int[] myArray){
        ...work here;
        return sortedArray;
    }

    int[] otherSort(int[] myArray){
        ...work here;
        return sortedArray;
        }
}

class mainClass{
   public static void main(String[]Args){
      test(manyFunctions.mergeSort);
      test(manyFunctions.otherSort);

   }

     boolean test(function someSortFunction){
        int n; // number of trials
        for (int i=0; i<=n ; i++) {
        int[] A = generateArray() // another function I made
            if (isSorted(someSortFunction(A)) = false) {
                return false;
            }
        }
     return true;
 }

Я не могу выяснить, как сделать это с немного я знаю о лямбда-выражениях и указатели на функции. Если это возможно, эта техника могла бы пригодиться.



18198
3
задан 7 февраля 2018 в 07:02 Источник Поделиться
Комментарии
1 ответ

Примечание: этот ответ основан на Java 8 и новее. Это не относится к Java 7, как Java 7 не поддерживает лямбда

Для начала, ваша функция тест ошибается в нескольких местах:

boolean test(function someSortFunction){//This is not how you pass functions
int n; //this has to be initialized
for (int i=0; i<=n ; i++) {//Depending on how n is used, you may have to use < instead of <=
int[] A = generateArray()//Missing semi-colon
if (isSorted(someSortFunction(A)) = false) {//Comparing is done with ==, not =
return false;
}
}
return true;
}

Для того, чтобы передать функцию, вы можете использовать Consumer<Void>, Supplier<Void>, Predicate<Void> или Function<Void, Void> (не использовать Void типа если у вас есть возвращаемые значения)

Поставщик определяет тип возврата, потребитель определяет тип входного сигнала и функцию обеих. Смысл:


  • Использование предиката, когда у вас есть тип boolean возвращение с аргументами

  • Польза поставщика, когда у вас есть возвращаемый тип

  • Бытового использования, когда у вас есть аргумент

  • Использовать функцию, если у вас есть оба аргумента и возвращаемое значение

Поскольку у вас обоих аргументов и возвращаемых типов, использовать Function. Первый аргумент вы даете это аргумент, который он получает, и вторая-это тип возвращаемого значения. Для примера, в вашем случае, это будет:

boolean test(Function<int[], int[]> someFunction) 

Используя Function требует называть apply для выполнения метода:

int[] res = someFunction.apply(input);

Прежде чем я двигаться дальше, я хотел бы взять вторую упомянуть соглашения об именовании. В Java, имена классов всегда начинаются с заглавной буквы. Экземпляров и функции начинаются с большой буквы. Так что ваши занятия будут:

public class ManyFunctions {...}
public class MainClass {...}

Прохождение методы не делается с помощью someClass.someFunction. В вашем случае, поскольку вы не используете статические методы, нужно создать экземпляр:

ManyFunctions functions = new ManyFunctions();

теперь, вы передаете функции:

test(functions::mergeSort);

если сделать методы статическими, вы можете просто пропустить экземпляр и использовать имя класса напрямую:

test(ManyFunctions::mergeSort);

Так что ваш класс будет:

class MainClass{
public static void main(String[] args){
ManyFunctions manyFunctions = new ManyFunctions();
test(manyFunctions::mergeSort);//Notice the missing "()" and arguments
test(manyFunctions::otherSort);

}

boolean test(Function<int[], int[]> someSortFunction){
int n = 10;//THIS HAS TO BE INITIALIZED! Otherwise, it won't compile
for (int i=0; i<=n ; i++) {
int[] A = generateArray();
if (isSorted(someSortFunction.apply(A)) == false) {//comparing is done with ==
return false;
}
}
return true;
}
}//Don't know if it was a copy-paste problem or not, but you had a missing bracket

7
ответ дан 7 февраля 2018 в 08:02 Источник Поделиться