Reputation: 4719
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
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
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
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