user2572526
user2572526

Reputation: 1279

Java8 pass a method as parameter using lambda

I would like to create a class that store a list of methods references and then executes all of them using Java 8 Lambda but I have some problem.

This is the class

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);
        }
    }
}

This is the class that I created for test

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!");
    }
}

But there is something wrong when I pass this::aMethod using me.addFunction.

What is wrong?

Upvotes: 5

Views: 7737

Answers (2)

Tagir Valeev
Tagir Valeev

Reputation: 100139

You should provide a suitable functional interface which abstract method signature is compatible with your method reference signature. In your case it seems that Runnable instead of Function should be used:

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);
    }
}

Also note that in static main method this is not defined. Probably you wanted something like this:

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

Upvotes: 4

Peter Lawrey
Peter Lawrey

Reputation: 533442

You can't refer to this in a static context as there is no this

me.addFunction(this::aMethod);

You need to refer to an instance or define your Function to take a Test object.

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

and

me.addFunction(Test::aMethod);

Upvotes: 4

Related Questions