Передача аргументов в метод ссылки

Учитывая этот метод:

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);
    }
Другие вопросы по тегам