3

I have a class which contains multiple methods:

Class SimpleClass {
    methodA(var1, var2) {
      //body
    }

    methodB(var1, var2) {
      //body
    }
    ....

}

Using java 8 Lambda, can I send one of the above methods as a parameter into another function of some other class? Something like below:

Class Service {
   doService(Method arg) {
     //Invoke passed simple class method here
     arg()
   }

}
suraj bahl
  • 2,864
  • 6
  • 31
  • 42
  • Is there an instance of `SimpleClass`? Or are the methods static? – shmosel Oct 26 '16 at 18:37
  • 1
    The linked question was asked way back before Java 8, but has since [gained new answers](http://stackoverflow.com/a/25005082/1743880) with the "Java 8 way" to do it and is effectively the canonical question on this matter. – Tunaki Oct 26 '16 at 20:12

2 Answers2

4

If doService has the appropriate signature, you can write:

service.doService(mySimpleClass::methodA);

Full example:

class SimpleClass {
  public void methodA(String a, String b) {
    System.out.println(a + b);
  }
  //other methods
}

class Service {
  public void doService(BiConsumer<String, String> consumer) {
    consumer.accept("Hel", "lo");
  }
}

public static void main(String[] args) {
  SimpleClass sc = new SimpleClass();
  new Service().doService(sc::methodA); //prints Hello
}
assylias
  • 321,522
  • 82
  • 660
  • 783
3

Fully working example

import java.util.function.BiConsumer;
class SimpleClass {
    void methodA(String a, String b) {
        System.out.printf("%s %s", a, b);
    }
}
class Service {
    void doService(BiConsumer<String,String> method) {
        method.accept("Hola", "mundo");
    }
}
class Main {
    public static void main( String ... args ) { 
        SimpleClass sc = new SimpleClass();
        Service s = new Service();
        s.doService(sc::methodA);
    }
}

Because there are no function types in Java 8 you have to specify your service signature to accept one of the functional interfaces.

In general terms if the method accepts arguments but doesn't returns a result: it's a Consumer. If it returns a Boolean then it's a Predicate and if it returns some other value it's a Function. There are others like Supplier and others.

In an ideal world we would've written:

class Service {
   void doService( void(String,String) method /*<-- fictional method type*/ ) { 
      method("Hello", "world");
   }
} 

But we have to use those functional interfaces at the moment.

This is a very good read about method references in Java 8

OscarRyz
  • 196,001
  • 113
  • 385
  • 569
  • What is the signature of doService? – bhspencer Oct 26 '16 at 18:41
  • 1
    @bhspencer updated the example – OscarRyz Oct 26 '16 at 18:49
  • @OscarRyz: Thx for the reply. Can i also pass collection of SimpleClass to service and in service iterate through the collection of simpleclass objects & invoke one of the method of simpleclass. Right now, i cannot do it because methods in simple class are instance methods. – suraj bahl Oct 26 '16 at 18:57
  • @surajbahl Yes, you can do that, if things get too complicated probably you would be better off by having a regular method invocation: `for( Item i : aCollection ) { i.methodX(); }` granted all the items in the collection are instances of an specific class/interface – OscarRyz Oct 26 '16 at 19:02
  • @OscarRyz: Can you give me a small snippet to do it? I cannot invoke method directly as different methods can be called for example one caller can ask to invoke methodA on each object of collection while other can ask to invoke methodB – suraj bahl Oct 26 '16 at 19:07
  • @surajbahl Sure [here it is](https://gist.github.com/OscarRyz/3ca018ab84d82641b9c6cd76fffc9c28) but in my opinion and depending of what you want to achive, there are maybe some other options. – OscarRyz Oct 26 '16 at 19:31