Сохраните метод в переменной java 8

Можно ли сохранить метод в переменную?
У меня есть класс, который называется MyFilter, и он фильтрует элементы в разных полях.
Конструктор MyFilter должен задать две вещи:

  1. Строка, например, элементы фильтра по языку, "английский"
  2. Это должен быть метод

например:

У меня есть элемент, и я хочу проверить, не указан ли язык == String для фильтра
Поэтому мне нужно получить язык этого элемента, поэтому Item.getLanguage()...
Мне также нужно это для Item.getTitle(), Item.getId() и так далее.

Я думаю, что это возможно с лямбдой, но я не знаю, как это сделать.

Ответ 1

Да, вы можете иметь переменную ссылку на любой метод. Для простых методов обычно достаточно использовать java.util.function. классы. Для сложных методов вам необходимо определить ваш @FunctionalInterface с помощью этого метода. Здесь рабочий пример:

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class Main {

    public static void main(String[] args) {
        final Consumer<Integer> simpleReference = Main::someMethod;
        simpleReference.accept(1);
        simpleReference.accept(2);
        simpleReference.accept(3);

        final ComplexInterface complexReference = Main::complexMethod;
        final String complexResult = complexReference.someMethod("888", 321, new ArrayList<>());
        System.out.println(complexResult);
    }

    private static void someMethod(int value) {
        System.out.println(value);
    }

    private static String complexMethod(String stringValue, int intValue, List<Long> longList) {
        final StringBuilder builder = new StringBuilder();
        builder.append(stringValue).append(" : ").append(intValue);
        for (Long longValue : longList) {
            builder.append(longValue);
        }
        return builder.toString();
    }

    @FunctionalInterface
    public static interface ComplexInterface{
        String someMethod(String stringValue, int intValue, List<Long> longList);
    }
}

Ответ 2

Вы можете использовать ссылки на методы Java 8. Вы можете использовать :: оператор, чтобы получить ссылку на метод из объекта.

import java.util.function.IntConsumer;

class Test {
    private int i;
    public Test() { this.i = 0; }
    public void inc(int x) { this.i += x; }
    public int get() { return this.i; }

    public static void main(String[] args) {
        Test t = new Test();
        IntConsumer c = t::inc;
        c.accept(3);
        System.out.println(t.get());
        // prints 3
    }
}

Вам просто нужен @FunctionalInterface который соответствует сигнатуре метода, который вы хотите сохранить. java.util.function содержит выбор наиболее часто используемых.

Ответ 3

Вы можете использовать ссылку на метод, например -

System.out::println  

Что эквивалентно лямбда-выражению -

x -> System.out.println(x).  

Кроме того, вы можете отражать пользователя для хранения метода, и он будет работать и для более ранней версии java.