Remark 1 : It is observed that there are
1 and three methods under the functional interface.
1.1 The only abstract method
1.2 Use default to define common methods (default methods) and call them through objects .
After implementing the interface, because the default method is not an abstract method, it does not need to be overridden, but it can also be overridden if required for development. Of course, if the default method in the interface cannot meet the needs of an implementation class, then the implementation class can override the default method. The signature is the same as the interface default method, but the default modifier cannot be added.
3. Use static to define static methods and call them through the interface name .
2. A new annotation
If an interface is now created for functional interface, when it is defined, let it have only one abstract method, so there is a new annotation: functional interface @FunctionInterface
Remark 2 : Regarding lambda expressions
before JDK8, interfaces can be implemented through anonymous inner classes
Function<Integer, String> fun = new Function<Integer, String>() {
@Override
public String apply(Integer t) {
return String.valueOf(t);
}
};
In JDK8, implemented through lambda expressions
Function<Integer, String> fun = (x) -> String.valueOf(x);
It can be concluded that lambda expressions are born to optimize anonymous inner classes.
String res = fun.apply(1000);
System.out.println(res);
1. Function functional interface
The Function interface accepts an input parameter T and returns a result R.
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Function<T, R> {
// 接受输入参数,对输入执行所需操作后 返回一个结果。
R apply(T t);
// 返回一个 先执行before函数对象apply方法,再执行当前函数对象apply方法的 函数对象。
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
// 返回一个 先执行当前函数对象apply方法, 再执行after函数对象apply方法的 函数对象。
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
// 返回一个执行了apply()方法之后只会返回输入参数的函数对象。
static <T> Function<T, T> identity() {
return t -> t;
}
}
Example: use of the apply method
public class FunctionDemo {
static int modifyTheValue(int valueToBeOperated, Function<Integer, Integer> function) {
return function.apply(valueToBeOperated);
}
public static void main(String[] args) {
int myNumber = 10;
// 使用lambda表达式实现函数式接口
// (x)->(x)+20 输入一个参数x,进行加法运算,返回一个结果
// 所以该lambda表达式可以实现Function接口
int res1 = modifyTheValue(myNumber, (x)-> x + 20);
System.out.println(res1); // 30
// 使用匿名内部类实现
int res2 = modifyTheValue(myNumber, new Function<Integer, Integer>() {
@Override
public Integer apply(Integer t) {
return t + 20;
}
});
System.out.println(res2); // 30
}
}
Example: the andThen method uses
public static Integer modifyTheValue2(int value, Function<Integer, Integer> function1, Function<Integer, Integer> function2){
//value作为function1的参数,返回一个结果,该结果作为function2的参数,返回一个最终结果
return function1.andThen(function2).apply(value);
}
public static void main(String[] args) {
System.out.println(modifyTheValue2(3, val -> val + 2, val -> val + 3));
}
2. Consumer functional interface
Represents an operation that accepts one input parameter and returns nothing
Example: use of the accept method
public static void modifyTheValue3(int value, Consumer<Integer> consumer) {
consumer.accept(value);
}
public static void main(String[] args) {
// (x) -> System.out.println(x * 2)接受一个输入参数x
// 直接输出,并没有返回结果
// 所以该lambda表达式可以实现Consumer接口
modifyTheValue3(3, (x) -> System.out.println(x * 2));
}
output:
6
3. Predicate assertion functional interface
Takes one input parameter and returns a boolean result.
Example: The test method uses 1
public static boolean predicateTest(int value, Predicate<Integer> predicate) {
return predicate.test(value);
}
public static void main(String[] args) {
// (x) -> x == 3 输入一个参数x,进行比较操作,返回一个布尔值
// 所以该lambda表达式可以实现Predicate接口
System.out.println(predicateTest(3, (x) -> x == 3));
}
output:
true
Example: The test method uses 2
public static void eval(List<Integer> list, Predicate<Integer> predicate) {
for (Integer n : list) {
if (predicate.test(n)) {
System.out.print(n + " ");
}
}
// list.forEach(n -> {
// if (predicate.test(n)) {
// System.out.print(n + " ");
// }
// });
}
public static void main(String args[]) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
// Predicate<Integer> predicate = n -> true
// n 是一个参数传递到 Predicate 接口的 test 方法
// n 如果存在则 test 方法返回 true
System.out.println("输出所有数据:");
// 传递参数 n
eval(list, n -> true);
// Predicate<Integer> predicate1 = n -> n%2 == 0
// n 是一个参数传递到 Predicate 接口的 test 方法
// 如果 n%2 为 0 test 方法返回 true
System.out.println("\n输出所有偶数:");
eval(list, n -> n % 2 == 0);
// Predicate<Integer> predicate2 = n -> n > 3
// n 是一个参数传递到 Predicate 接口的 test 方法
// 如果 n 大于 3 test 方法返回 true
System.out.println("\n输出大于 3 的所有数字:");
eval(list, n -> n > 3);
}
output:
输出所有数据:
1 2 3 4 5 6 7 8 9
输出所有偶数:
2 4 6 8
输出大于 3 的所有数字:
4 5 6 7 8 9
Example: The test method uses 3
public static boolean validInput(String name, Predicate<String> function) {
return function.test(name);
}
public static void main(String args[]) {
String name = "冷冷";
if(validInput(name, s -> !s.isEmpty() && s.length() <= 3 )) {
System.out.println("名字输入正确");
}
}
3. Supplier supply type functional interface
No arguments, returns a result.
Example: use of get method
public static String supplierTest(Supplier<String> supplier) {
return supplier.get();
}
public static void main(String args[]) {
String name = "冷冷";
// () -> name.length() 无参数,返回一个结果(字符串长度)
// 所以该lambda表达式可以实现Supplier接口
System.out.println(supplierTest(() -> name.length() + ""));
}
output:
2