Руководство Java Functional Interface
View more Tutorials:


Functional Interface - это новая концепция, введенная в Java начиная с версии 8, которая представляет собой interface только с одним абстрактным методом. Выражения Lambda часто используются для быстрого создания объекта Functional Interface.
Ниже приведен Functional Interface с одним абстрактным методом:
package org.o7planning.ex;
public interface Greeting {
String greeting(String name);
default String hello(String name) {
return "Hello " + name;
}
}
Если interface предназначен для functional interface, вы должны использовать annotation @FunctionalInterface для аннотирования (anotate) его. Хотя не требуется, но это облегчает другим понимание вашей дизайнерской идеи. Он также помогает компилятору (compiler) сообщать о ваших ошибках во время разработки приложения. Например, компилятор будет помечать ошибку, если существует interface, аннотированный @FunctionalInterface, но имеющий более одного абстрактного метода.
package org.o7planning.ex;
@FunctionalInterface
public interface Greeting {
String greeting(String name);
default String hello(String name) {
return "Hello " + name;
}
}
Продолжим с приведенным выше примером. До Java 8 для создания объекта Greeting вам нужно было создать класс, а затем реализовать абстрактный метод Greeting. Это довольно многословно.
UsingGreetingBeforeJ8.java
package org.o7planning.ex;
public class UsingGreetingBeforeJ8 {
public static void main(String[] args) {
// Create Greeting object:
Greeting obj = new Greeting() {
@Override
public String greeting(String name) {
return "Hi " + name;
}
};
System.out.println(obj.greeting("Tran"));
System.out.println(obj.hello("Tran"));
}
}
В принципе, Functional Interface включает в себя только 1 абстрактный метод, поэтому вам нужно только реализовать этот метод. Выражение Lambda из Java 8 поможет вам более сжато переписать предыдущий пример.
UsingGreetingJ8A.java
package org.o7planning.ex;
public class UsingGreetingJ8A {
public static void main(String[] args) {
// Create Greeting object with Lambda expression:
Greeting obj = (String name) -> {
return "Hi " + name;
};
System.out.println(obj.greeting("Tran"));
System.out.println(obj.hello("Tran"));
}
}
Типы данных параметров в абстрактном методе Greeting известны, поэтому нет необходимости их переписывать. Мы можем переписать предыдущий пример более сжато:
Greeting obj = (name) -> {
return "Hi " + name;
};
Если абстрактный метод имеет только один параметр, то вам, вероятно, не нужны круглые скобки (parentheses) () в выражении Lambda:
Greeting obj = name -> {
return "Hi " + name;
};
Если содержимое метода состоит только из одного выражения, вам могут не понадобиться фигурные скобки (braces) {} и не нужно писать ключевое слово "return".
Greeting obj = name -> "Hi " + name;
В результате код предыдущего примера намного короче:
UsingGreetingJ8.java
package org.o7planning.ex;
public class UsingGreetingJ8 {
public static void main(String[] args) {
// Create Greeting object with Lambda expression:
Greeting obj = name -> "Hi " + name;
System.out.println(obj.greeting("Tran"));
System.out.println(obj.hello("Tran"));
}
}
Output:
Hi Tran
Hello Tran
Далее мы рассмотрим некоторые Functional Interface, включая действительные и недействительные, и объясним, почему они недействительны:
Следующий IEquals interface не является functional interface, поскольку метод "public boolean equals(Object)" является членом, унаследованным от класса Object. Таким образом, считается, что IEquals не имеет абстрактных методов и не подходит для functional interface.
IEquals.java (Invalid!)
package org.o7planning.j8fi;
@FunctionalInterface
public interface IEquals {
boolean equals(Object other);
}
Действительны:
IComparator.java (OK, Valid!)
package org.o7planning.j8fi;
@FunctionalInterface
public interface IComparator<T> {
int compareTwoObject(T obj, T other);
boolean equals(Object other);
}
Метод clone() класса Object является protected(не является общедоступным). Поэтому следующий interface IWithClone считается действительным functional interface .
IWithClone.java (OK, Valid)
package org.o7planning.j8fi;
@FunctionalInterface
public interface IWithClone {
Object clone();
}

Interface CC на приведенной выше иллюстрации является действительным functional interface, поскольку абстрактные методы, которые он наследует от AA и BB, одинаковы.
Ниже приведены некоторые из наиболее широко используемых functional interface в Java:
