5

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?

5
  • 5
    But there is something wrong when I pass this::aMethod - it's because there is a mistake somewhere. If you want more specific answer - give more specific question. Commented Aug 18, 2015 at 14:56
  • Post the specific error you're getting and a more specific question Commented Aug 18, 2015 at 14:58
  • 2
    A Function takes an argument and has a return value. aMethod has neither. Commented Aug 18, 2015 at 14:59
  • And how can I manage methods that have no arguments and no return value? Commented Aug 18, 2015 at 15:00
  • 2
    If at some point you want to use a Function (as defined in the java.util.function package) make sure to provide type arguments, as in Function<String,Integer> (or whatever). The examples here use the Function raw type, which will effectively disable type inference. Commented Aug 18, 2015 at 20:24

2 Answers 2

4

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);
Sign up to request clarification or add additional context in comments.

1 Comment

You don’t need a stream() to run all elements. Just listOfMethodsToExecute.forEach(Runnable::run);
4

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.