Как передать функцию в качестве параметра в Java, чтобы запускать ее несколько раз

#java

#java

Вопрос:

Извините, что задаю этот вопрос, я видел, что его часто задавали, но не так, как я думаю.

Моя цель — создать функцию повтора, которая будет выполнять цикл «n» времени, чтобы попытаться запустить метод, который я передаю в качестве параметра.

Итак, в этом случае я хочу запустить функцию «myFunction ()», но я знаю, что иногда возвращаемое значение равно false, и я хочу запускать его до тех пор, пока возвращаемое значение не станет true.

Вот как я хотел бы, чтобы она запускалась :

 public static void main (String [] args){
    boolean did work = retry (myFunction(),5)
    if(didwork){
        System.out.println("I found my stuff");
    } else {
        System.out.println("I didn't found my stuff");
    }
}

public boolean retry (Function function, int loopTry){
    boolean success = false;
    for(int i=0 ; i<loopTry ; i  ){
        success = function.run();
        if(success){
            break;
        }
    }
    return success;
}

public boolean myFunction(){
    boolean found = false;
    //do stuff
    if(stuff){
        found = true;
    }
    return found;
}
  

Я знаю, что это невозможно (по крайней мере, в java 7, возможно, в 8)

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

Итак, я хотел бы знать, есть ли «чистый» способ сделать это (даже в java 8) или нет?

Спасибо

Комментарии:

1. Создайте интерфейс с myFunction. Затем реализует один класс с нужным вам материалом. Вам нужно будет передать экземпляр этого класса retry для вызова функции.

2. Похоже, что ваша функция не имеет ввода и имеет вывод. Взгляните на Supplier интерфейс в Java 8. docs.oracle.com/javase/8/docs/api/java/util/function /…

3. retry принимает Function параметр объекта, а не a boolean . Компилируется ли этот код?

4. Для Java 8 посмотрите на лямбды и java.util.function функциональные интерфейсы. Для до Java 8 посмотрите на отражение.

5. В Java 8 вы говорите retry(this::myFunction) .

Ответ №1:

Вы могли бы попробовать reflection здесь:

Например:

 public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException,
            IllegalArgumentException, InvocationTargetException {

  Method method = Test.class.getMethod("myFunction");

  boolean didwork = retry(method, 5);
  if (didwork) {
      System.out.println("I found my stuff");
  } else {
      System.out.println("I didn't found my stuff");
  }

}

public static boolean retry(Method method, int loopTry)
        throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {

  boolean success = false;
  for (int i = 0; i < loopTry; i  ) {
    success = (Boolean) method.invoke(null);
    if (success) {
      break;
    }
  }
  return success;
}

public static boolean myFunction() {
  boolean found = false;

  //do stuff
  if(stuff){
     found = true;
  }

  return found;
}
  

Комментарии:

1. Спасибо за ваш ответ, это было довольно близко к работе. Мне пришлось сделать их не статичными и предоставить экземпляр объекта (в данном случае Test) в качестве параметра для вызова, и это сработало

Ответ №2:

Вы могли бы просто добавить цикл while в myFunction(), который «повторяет попытку» внутри функции. Это будет всего лишь одна дополнительная строка. Максимум два или три, если вы определяете максимальное количество попыток как n. Во втором случае вы воссоздали эффект либо попытки, пока не получите значение true, либо пока не будет достигнуто число попыток.

Комментарии:

1. Дело в том, что я не хочу выполнять только цикл, который я хочу выполнять с несколькими вещами между каждой попыткой, и я хочу использовать эту функцию повтора для нескольких функций. Мне просто интересно, можно ли избежать нескольких циклов внутри каждой моей функции, создав эту функцию «повтора»