Реализации функционального интерфейса и варианты использования - PullRequest
3 голосов
/ 27 мая 2019

Я просто пытался написать функциональный интерфейс, чтобы понять различные варианты использования.

Глядя на приведенный ниже код, я понимаю, что у меня могут быть разные реализации с использованием лямбда-выражений.Помимо этого кто-нибудь может показать сложные реализации?

Можно ли использовать другой метод по умолчанию, например addLikeOtherWay в лямбда-выражении?если да как в моем примере?

Зачем мне интерфейс только с одним абстрактным методом?Какой был бы случай использования только одного абстрактного метода в моем интерфейсе?

public class Calculator {

    public static void main(String[] args) {
        ICalculator i = (int a, int b) -> a + b;
        System.out.println(i.add(5, 2));
        i = (int a, int b) -> a + b + a;
        System.out.println(i.add(5, 2));
    }
}

@FunctionalInterface
interface ICalculator {

    public int add(int a, int b);

    default int addLikeThis(int a, int b) {
        return a + b;
    }

    default int addLikeOtherWay(int a, int b) {
        return a + b + a + b;
    }

}

Ответы [ 2 ]

1 голос
/ 28 мая 2019

"Можно ли использовать метод по умолчанию в лямбда-выражении?"Да.Фактически, многие функциональные интерфейсы содержат методы по умолчанию.Вам нужен один и только один абстрактный метод в интерфейсе, чтобы он был функциональным интерфейсом, в противном случае были бы другие методы интерфейса, «не реализованные» лямбда-выражением, что недопустимо.Но вот как могут применяться значения по умолчанию.Приведенный ниже интерфейс BiFunction был извлечен из исходников API, без JavaDoc.

Следующий код работает, потому что BinaryOperator и UnaryOperator расширяют BiFunction и Function соответственно.

      BinaryOperator<Integer> add = (numb1,numb2)->numb1+numb2;
      UnaryOperator<Integer> mul = resultFromAdd->resultFromAdd*20;
      BinaryOperator<Integer> addThenMul = (numb1,numb2) ->add.andThen(mul).apply(numb1,numb2);
      int result = addThenMul.apply(10,20); // produces (10+20)*20 = 600

Следующее было поднято из исходных файлов Java API.

       @FunctionalInterface
       public interface BiFunction<T, U, R> {

          R apply(T t, U u);

          default <V> BiFunction<T, U, V> andThen(
                Function<? super R, ? extends V> after) {
             Objects.requireNonNull(after);
             return (T t, U u) -> after.apply(apply(t, u));
          }
       }

В приведенном выше примере кода я мог бы использовать BiFunction<Integer,Integer,Integer> и Function<Integer,Integer>.Но расширения *Operator предполагают одинаковый тип для всех аргументов, поэтому их проще использовать (т. Е. Меньше вводить).

0 голосов
/ 28 мая 2019

Зачем мне интерфейс только с одним абстрактным методом?Какой был бы случай использования только одного абстрактного метода в моем интерфейсе?

Для облегчения использования лямбда-выражений, которые являются безымянными функциями.Лямбда-выражения делают код выразительным и уменьшают беспорядок.Это также делает код более читабельным.Это основано на моем опыте работы с лямбда-выражениями.

...