Передача аргументов в метод ссылки
Учитывая этот метод:
private static Integer getVal(Integer a, Integer b){
return a + b;
}
который можно назвать лямбда-выражением:
a -> getVal(1, 2)
Есть ли способ превратить это в ссылку на метод, что-то вроде:
Class::getVal
Спасибо
3 ответа
Что ж, если вы передаете константы в вызов метода, вы можете создать другой метод, который вызывает оригинальный метод:
private static Integer getVal (Integer a) {
return getVal(1,2);
}
тогда вы можете использовать ссылку на метод для второго метода.
то есть вы можете изменить
a -> getVal(1, 2)
в
ClassName::getVal
Тем не менее, это не имеет особого смысла.
PS, не ясно, какова цель a
в вашем лямбда-выражении, так как вы игнорируете его.
В общем случае вы можете передать ссылку на метод данного метода, если она соответствует сигнатуре единственного метода требуемого функционального интерфейса.
Пример:
public static Integer apply (BinaryOperator<Integer> op, Integer a, Integer b)
{
return op.apply(a,b);
}
Теперь вы можете позвонить:
apply(ClassName::getVal)
с вашим оригинальным методом.
Вот пример.
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);
}
}
Вам нужен функциональный интерфейс для использования ссылки на метод (в этом примере Operator
). И вам также нужен метод, который принимает экземпляр функционального интерфейса в качестве его parermater (в этом примере operate(int a, int b, Operator operator
).
ОБНОВИТЬ
Если вам нужна обёртка объекта, просто измените operate
метод для
static int operate(ObjectWrapper wrapper, Operator operator) {
return operator.operate(wrapper.getA(), wrapper.getB());
}
А потом позвони operate
метод:
int result = operate(wrapper, Calc::add);
getVal() будет использоваться только в качестве ссылки на метод в тех местах, где ожидается функциональный интерфейс применимого типа, например, BiFunction или IntBinaryOperator, или пользовательский функциональный интерфейс (как в ответе zhh)
Пример:
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);
}