7

so I do have code like this:

public ConsumerTestClass(Consumer<String> consumer) {

}

public static void printString(String text) {
    System.out.println(text);

}

And from the method of other class, I would like to create object of ConsumerTestClass:

new ConsumerTestClass(/*passing consumer here*/);

And as a consumer I would like to pass ConsumerTestClass::printString, but to be able to do that I need to pass argument as well, so it looks like that: (text) -> ConsumerTestClass.printString(text). And my question is... Is it only option to pass Consumer, or method which is accepting one argument and returning no results?

Naman
  • 27,789
  • 26
  • 218
  • 353
Suule
  • 2,197
  • 4
  • 16
  • 42

2 Answers2

10

The method reference ConsumerTestClass::printString is just a syntactic sugar to the equivalent lambda expression text -> ConsumerTestClass.printString(text)

A method reference can't be used for any method. They can only be used to replace a single-method lambda expression. In general, we don't have to pass paremeters to method references. In this case, parameters taken by the method printString are passed automatically behind the scene.

method references provides a way to generate function objects even more succinct than lambdas.

So prefer method references to lambdas as a good practice.

Here's the fully working example.

public class ConsumerTestClass {
    public ConsumerTestClass(Consumer<String> consumer) {
        consumer.accept("Test");
    }

    public static void printString(String text) {
        System.out.println(text);

    }

    public static void main(String[] args) {
        new ConsumerTestClass(ConsumerTestClass::printString);
    }
}

The bottom line is that you have to pass in the argument when you call the accept method of the Consumer as done inside the constructor above.

Ravindra Ranwala
  • 20,744
  • 6
  • 45
  • 63
4

You can pass it as :

new ConsumerTestClass(ConsumerTestClass::printString);

which is a method reference for

new ConsumerTestClass(x -> ConsumerTestClass.printString(x));

Is it only option to pass Consumer, or method which is accepting one argument and returning no results?

It depends on your use case, for example, if you want to pass two arguments and still not return anything from them, you can look into the BiConsumer class as well.

Note: A special case, when you don't want to perform any operation on the Consumer supplied, you can chose to define it as no-op lambda, as in:

new ConsumerTestClass(s -> {});
Naman
  • 27,789
  • 26
  • 218
  • 353