2015-08-18 3 views
4

Я хотел бы создать класс, который хранит список ссылок на методы, а затем выполняет их все с использованием Java 8 Lambda, но у меня есть некоторые проблемы.Java8 передать метод как параметр, используя lambda

Это класс

public class MethodExecutor { 
    //Here I want to store the method references 
    List<Function> listOfMethodsToExecute = new LinkedList<>(); 

    //Add a new function to the list 
    public void addFunction(Function f){ 
     if(f!=null){ 
      listOfMethodsToExecute.add(f); 
     } 
    } 

    //Executes all the methods previously stored on the list 
    public void executeAll(){ 
     listOfMethodsToExecute.stream().forEach((Function function) -> { 
      function.apply(null); 
     } 
    } 
} 

Это класс, который я создал для испытания

public class Test{ 
    public static void main(String[] args){ 
     MethodExecutor me = new MethodExecutor(); 
     me.addFunction(this::aMethod); 
     me.executeAll();  
    } 

    public void aMethod(){ 
     System.out.println("Method executed!"); 
    } 
} 

Но есть что-то не так, когда я прохожу this::aMethod с помощью me.addFunction.

Что не так?

+5

'Но есть что-то не так, когда я прохожу этот :: aMethod' - это потому, что есть ошибка где-то. Если вы хотите получить более конкретный ответ - задайте более конкретный вопрос. –

+0

Опубликовать специальную ошибку, которую вы получаете, и более конкретный вопрос – Iamsomeone

+1

A ['Function'] (http://docs.oracle.com/javase/8/docs/api/java/util/function/Function.html) принимает аргумент и имеет возвращаемое значение. 'aMethod' не имеет ни того, ни другого. –

ответ

4

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

public class MethodExecutor { 
    List<Runnable> listOfMethodsToExecute = new ArrayList<>(); 

    //Add a new function to the list 
    public void addFunction(Runnable f){ 
     if(f!=null){ 
      listOfMethodsToExecute.add(f); 
     } 
    } 

    //Executes all the methods previously stored on the list 
    public void executeAll(){ 
     listOfMethodsToExecute.forEach(Runnable::run); 
    } 
} 

Также отметим, что в статическом main методе this не определен. Возможно, вы хотели что-то вроде этого:

me.addFunction(new Test()::aMethod); 
+2

Вам не нужен 'stream()' для запуска всех элементов. Просто 'listOfMethodsToExecute.forEach (Runnable :: run);' – Holger

+1

@Holger, спасибо, не обратил на это внимания. Ред. –

4

Вы не можете обратиться к this в static контексте, поскольку нет this

me.addFunction(this::aMethod); 

Вам нужно обратиться к экземпляру или определить функцию взять тестовый объект.

public void addFunction(Function<Test, String> f){ 
    if(f!=null){ 
     listOfMethodsToExecute.add(f); 
    } 
} 

и

me.addFunction(Test::aMethod); 
Смежные вопросы