user1052610
user1052610

Reputation: 4719

Passing arguments to Method References

Given this method:

private static Integer getVal(Integer a, Integer b){
   return a + b;
}

which can be called as a lambda:

a -> getVal(1, 2)

Is there anyway of turning this into a method reference, something like:

Class::getVal

Thanks

Upvotes: 1

Views: 2743

Answers (3)

zhh
zhh

Reputation: 2406

Here is an example.

interface Operator {
    int operate(int a, int b);
}

class Calc {
    public static int add(int a, int b) {
        return a + b;
    }
}

class Main {    
    public static void main(String[] args) {
        // using method reference
        int result = operate(1, 2, Calc::add);
        // using lambda
        int result = operate(1, 2, (a, b) -> Calc.add(a, b));
    }

    static int operate(int a, int b, Operator operator) {
        return operator.operate(a, b);
    }
}

You need a functional interface to use method reference (In this example Operator). And you also need a method which accepts an instance of the functional interface as its parermater (In this example operate(int a, int b, Operator operator).

UPDATE

If you need an object wrapper, just change the operate method to

static int operate(ObjectWrapper wrapper, Operator operator) {
    return operator.operate(wrapper.getA(), wrapper.getB());
}

And then call the operate method:

int result = operate(wrapper, Calc::add);

Upvotes: 2

Ward
Ward

Reputation: 2828

getVal() will only be usable as a method reference, in places where a functional interface of an applicable type is expected, such as BiFunction or IntBinaryOperator, or a custom functional interface (as in the answer of zhh)

Example:

    public static void main(String[] args) {
        Integer result1 = calculate(1, 2, Second::getVal);
        Integer result2 = calculateAsInt(1, 2, Second::getVal);
    }

    private static Integer getVal(Integer a, Integer b){
        return a + b;
    }

    private static Integer calculate(Integer a, Integer b, BinaryOperator<Integer> operator) {
        return operator.apply(a, b);
    }

    private static int calculateAsInt(int a, Integer b, IntBinaryOperator operator) {
        return operator.applyAsInt(a, b);
    }

Upvotes: 1

Eran
Eran

Reputation: 394146

Well, if you are passing constants to the method call, you can create another method that calls the original method:

private static Integer getVal (Integer a) {
    return getVal(1,2);
}

then you can use method reference for the second method.

i.e. you can change

a -> getVal(1, 2)

to

ClassName::getVal

That said, it doesn't make much sense.

P.S., it's not clear what's the purpose of a in your lambda expression, since you are ignoring it.

In general you can pass a method reference of a given method if it matches the signature of the single method of the required functional interface.

Example:

public static Integer apply (BinaryOperator<Integer> op, Integer a, Integer b)
{
    return op.apply(a,b);
}

Now you can call:

apply(ClassName::getVal)

with your original method.

Upvotes: 2

Related Questions