0

I forgot a concept that I used and can't remember it.

For the context, I used to have a method like toString() which had a parameter. This parameters allowed me to call my method like myMethod(System.out::println) to print it on the screen, but also to print it in a file with the same syntax.

Does anyone know what can be this parameter? the concept? I think it's kind of a FunctionalInterface but I don't know what it is.

pts
  • 80,836
  • 20
  • 110
  • 183
Torarn
  • 402
  • 3
  • 11

3 Answers3

2

This is called method reference and applies when you know what method you want to call, provided the method already exist.

From the tutorial :

Because this lambda expression invokes an existing method, you can use a method reference instead of a lambda expression:

Arrays.sort(rosterAsArray, Person::compareByAge);

Available since Java-8.

An exemple using what you want:

    public static void function(String s, Consumer<String> f) {
    f.accept(s);
}

public static void main(String args[]) {
    String test1 = "test";
    String test2 = "test2";
    function(test1, System.out::println);
    function(test2, System.out::println);
    function(test1, System.out::print);
    function(test2, System.out::print);
}
Cédric Couralet
  • 4,913
  • 1
  • 21
  • 21
  • Yes that's what I'm searching for. In the tutorial, it's used with a "Comparator" that will provide the compare method. What i want to know is how to find this provider for other method. In my previous example, I'm searching for the "println" provider. – Torarn Jun 19 '14 at 09:28
  • +1 for using `Consumer` (wanter to alert that `Consumer extends String>` would be better, but String is final class :3) – kajacx Jun 19 '14 at 09:43
  • The use of the function(String, Consumer) is how i want it. But does the Comsumer.accept trigger the println method? – Torarn Jun 19 '14 at 09:50
  • yes, per the javadoc : accept(T t) `Performs this operation on the given argument.` – Cédric Couralet Jun 19 '14 at 10:26
  • Thanks a lot. I caon't try it for now, but it realy helps. Have a good day – Torarn Jun 19 '14 at 11:19
0

Would this work for you?

public class C {
  static void myMethod(java.io.PrintStream p) {
    p.println("Hello!");
  }
  public static void main(String args[]) {
    myMethod(System.out);
  }
}

Unfortunately you can't pass System.out.println directly, because in Java methods (before Java 8) are not first-class objects. All you can do with a method is calling it. As a workaround, you can introduce an interface and create an adapter class.

pts
  • 80,836
  • 20
  • 110
  • 183
  • 1
    Since Java8 we can pass method to directly. We can pass a "lambda", it's a method that we created in our code (for example, we can give a method run directly to a Thread instead of creating the Runnable before). But we can pass existing methods, and th'ats what i'm looking for. CédricC is on the right way with his respons : http://stackoverflow.com/a/24303031/3755297 – Torarn Jun 19 '14 at 09:34
0

This goes well with java 8 functional interface:

@FunctionalInterface
static interface MyPrinter {
    public void println(String line);
}

static void myMethod(MyPrinter mp) {
    mp.println("Hello wolrd");
}

...

public static void main(String[] args) throws IOException {
    myMethod(System.out::println);

    PrintWriter pw = new PrintWriter("myFile.txt");
    myMethod(pw::println);
    pw.close(); //never forget to close file output streams!

    //EDIT: note that you can of course store your MyPrinter in a variable:
    MyPrinter mp = System.err::println;
    myMethod(mp);
}
kajacx
  • 12,361
  • 5
  • 43
  • 70
  • A bit like that. But in my memories, it didn't need to create a functionnal interface as the println method was already existing. – Torarn Jun 19 '14 at 09:45