What is a functional interface
Let’s look at what a traditional create thread would look like, okay
Thread t1 = new Thread(new Runnable() { @Override public void run() { System.out.println("t1"); }}); t1.start();Copy the code
How about using functional interfaces
Thread t2 = new Thread(() -> System.out.println("t2"));
t2.start();
Copy the code
The Runnable interface can be written directly using Lambda expressions, because the Runnable interface is a functional interface. Take a look at the source of Runnable.
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
Copy the code
The interface is annotated with @functionalinterface, indicating that the interface is a FunctionalInterface.
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {
}
Copy the code
In JDK8, in addition to the Runnbale interface, other Comparator and Callable interfaces use this annotation to define them as functional interfaces.
Built-in functional interfaces
JDK8 provides several built-in functional interfaces that can be used in a wide range of apis and can be used for most applications.
//Consumer<T> -t performs an action as input but returns no value Consumer<String> con = (x) -> {system.out.println (x); }; con.accept("hello world"); //Supplier<T> - Without any input, return T Supplier<String> supp = () -> {return "Supplier"; }; System.out.println(supp.get()); //Predicate<T> -t as input, Boolean as output Predicate<String> pre = (x) -> {system.out.print (x); //Predicate<T> -t as input, Boolean as output Predicate<String> pre = (x) -> {system.out.print (x); return x.startsWith("op"); }; System.out.println(": " + pre.test("op, hello World")); Function<String, String> Function = (x) -> {system.out.print (x + ": "); return "Function"; }; System.out.println(function.apply("hello world")); //BinaryOperator<T> - Two T's as input, return one T as output, BinaryOperator<String> bina = (x, y) -> {system.out. print(x + "" + y); return "BinaryOperator"; }; System.out.println(" " + bina.apply("hello ", "world"));Copy the code
Custom functional interfaces
1. Customize a functional interface
@FunctionalInterface
public interface CalcInterface<N, V> {
V operation(N n1, N n2);
}
Copy the code
There is only one abstract method here, the @functional Interface annotation doesn’t need to be written, but we can see why.
2. Create a class that references a functional interface
public static class NumberOperation<N extends Number, V extends Number> { private N n1; private N n2; public NumberOperation(N n1, N n2) { this.n1 = n1; this.n2 = n2; } public V calc(CalcInterface<N, V> ci) { V v = ci.operation(n1, n2); return v; }}Copy the code
3. Test functional interfaces
private static void testOperationFnInterface() { NumberOperation<Integer, Integer> np = new NumberOperation(13, 10); CalcInterface<Integer, Integer> addOper1 = (n1, n2) -> { return n1 + n2; }; CalcInterface<Integer, Integer> multiOper1 = (n1, n2) -> { return n1 * n2; }; System.out.println(np.calc1(addOper1)); System.out.println(np.calc1(multiOper1)); Println (np.calc1((n1, n2) -> n1 + n2)); System.out.println(np.calc1((n1, n2) -> n1 * n2)); }Copy the code
Final output:
23, 130, 23, 130Copy the code
Functional interface specification
1. @functionalinterface is identified as a FunctionalInterface that can only be used on interfaces that have only one abstract method.
Static methods in interfaces, default methods, and methods that override the Object class are not abstract methods.
The @functionalinterface annotation is not required. If the interface has only one abstract method that can be omitted, it complies with functional interfaces by default. However, it is recommended that this annotation be used everywhere, and the compiler will check if the interface complies with the FunctionalInterface specification.
For example
Proper functional interfaces.
@FunctionalInterface
public interface CalcInterface<N, V> {
V operation(N n1, N n2);
}
Copy the code
It doesn’t matter if you add a few methods that conform to the function, and the compiler doesn’t give an error.
@FunctionalInterface
public interface CalcInterface<N, V> {
V operation(N n1, N n2);
public boolean equals(Object object);
public default void defaultMethod() {
}
public static void staticMethod() {
}
}
Copy the code
This does not use @functionalInterface, but has two abstract methods that cannot be used in Lambda expressions.
public interface CalcInterface<N, V> {
V operation(N n1, N n2);
V operation2(N n1, N n2);
}
Copy the code
Compiling a FunctionalInterface annotated with @functionalinterface with two abstract methods will report an error.
@FunctionalInterface
public interface CalcInterface<N, V> {
V operation(N n1, N n2);
V operation2(N n1, N n2);
}
Copy the code
This does not have an abstract method, compilation error.
public interface CalcInterface<N, V> {
}
Copy the code
Recommended reading
Dry goods: Free 2TB architect four-stage video tutorial
Interview: the most complete Java multithreaded interview questions and answers
Tools: Recommended an online creation flow chart, mind mapping software
Share Java dry goods, high concurrency programming, hot technology tutorials, microservices and distributed technology, architecture design, blockchain technology, artificial intelligence, big data, Java interview questions, and cutting-edge hot news.