1. Origin of functional interface
We know that the premise of using Lambda expression is to have functional interface, and Lambda expression does not care about interface name and abstract method name. Only the parameter list and return value type of the abstract method are concerned. Therefore, in order to make it easier for us to use Lambda expressions, a large number of commonly used functional interfaces are provided in JDK
public class Demo01Fun { public static void main(String[] args) { fun1((arr)->{ int sum = 0 ; for (int i : arr) { sum += i; } return sum; }); } public static void fun1(Operator operator){ int[] arr = {1,2,3,4}; int sum = operator.getSum(arr); System.out.println("sum = " + sum); } } /** * Functional interface */ @FunctionalInterface interface Operator{ int getSum(int[] arr); }
2. Introduction to functional interface
The JDK provides us with functional interfaces, mainly in Java util. Function package.
2.1.Supplier
For interfaces with no parameters and return values, you need to provide a return data type for Lambda expressions.
@FunctionalInterface public interface Supplier<T> { /** * Gets a result. * * @return a result */ T get(); }
use:
/** * Supplier Use of functional interfaces */ public class SupplierTest { public static void main(String[] args) { fun1(()->{ int arr[] = {22,33,55,66,44,99,10}; // Calculate the maximum value in the array Arrays.sort(arr); return arr[arr.length-1]; }); } private static void fun1(Supplier<Integer> supplier){ // get() is an abstract method with no parameters and a return value Integer max = supplier.get(); System.out.println("max = " + max); } }
2.2.Consumer
The Supplier interface described above is used to produce data, while the Consumer interface is used to consume data. When using, you need to specify a generic type to define the parameter type
@FunctionalInterface public interface Consumer<T> { /** * Performs this operation on the given argument. * * @param t the input argument */ void accept(T t); }
Use: uniformly convert the input data to lowercase output
public class ConsumerTest { public static void main(String[] args) { test(msg -> { System.out.println(msg + "-> Convert to lowercase:" + msg.toLowerCase()); }); } public static void test(Consumer<String> consumer){ consumer.accept("Hello World"); } }
Default method: andThen
If all the parameters and return values of a method are of Consumer type, the effect can be achieved. When consuming a data, first do an operation, and then do an operation to realize the combination. This method is the default method and then method in the Consumer interface
default Consumer<T> andThen(Consumer<? super T> after) { Objects.requireNonNull(after); return (T t) -> { accept(t); after.accept(t); }; }
Specific operation
public class ConsumerAndThenTest { public static void main(String[] args) { test2(msg1->{ System.out.println(msg1 + "-> Convert to lowercase:" + msg1.toLowerCase()); },msg2->{ System.out.println(msg2 + "-> Convert to uppercase:" + msg2.toUpperCase()); }); } public static void test2(Consumer<String> c1,Consumer<String> c2){ String str = "Hello World"; //c1.accept(str); // Turn lowercase //c2.accept(str); // Capitalize //c1.andThen(c2).accept(str); c2.andThen(c1).accept(str); } }
2.3.Function
The Function interface is an interface with parameters and return values. The Function interface obtains data of another type from data of one type. The former is called a precondition and the latter is called a postcondition. There are parameters and return values.
@FunctionalInterface public interface Function<T, R> { /** * Applies this function to the given argument. * * @param t the function argument * @return the function result */ R apply(T t); }
Use: pass into a string and return a number
public class FunctionTest { public static void main(String[] args) { test(msg ->{ return Integer.parseInt(msg); }); } public static void test(Function<String,Integer> function){ Integer apply = function.apply("666"); System.out.println("apply = " + apply); } }
Default method: andThen, which is also used for combination operation
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); }
public class FunctionAndThenTest { public static void main(String[] args) { test(msg ->{ return Integer.parseInt(msg); },msg2->{ return msg2 * 10; }); } public static void test(Function<String,Integer> f1,Function<Integer,Integer> f2){ /*Integer i1 = f1.apply("666"); Integer i2 = f2.apply(i1);*/ Integer i2 = f1.andThen(f2).apply("666"); System.out.println("i2:" + i2); } }
2.4.Predicate
Interface with parameter and return value of Boolean
@FunctionalInterface public interface Predicate<T> { /** * Evaluates this predicate on the given argument. * * @param t the input argument * @return {@code true} if the input argument matches the predicate, * otherwise {@code false} */ boolean test(T t); }
use:
public class PredicateTest { public static void main(String[] args) { test(msg -> { return msg.length() > 3; },"HelloWorld"); } private static void test(Predicate<String> predicate,String msg){ boolean b = predicate.test(msg); System.out.println("b:" + b); } }
The default method in predict provides the logical relationship operation and or close isequals method
public class PredicateDefaultTest { public static void main(String[] args) { test(msg1 -> { return msg1.contains("H"); },msg2 -> { return msg2.contains("W"); }); } private static void test(Predicate<String> p1,Predicate<String> p2){ /*boolean b1 = predicate.test(msg); boolean b2 = predicate.test("Hello");*/ // b1 contains h and B2 contains W // p1 contains H and p2 contains W boolean bb1 = p1.and(p2).test("Hello"); // p1 contains H or p2 contains W boolean bb2 = p1.or(p2).test("Hello"); // p1 does not contain H boolean bb3 = p1.negate().test("Hello"); System.out.println(bb1); // FALSE System.out.println(bb2); // TRUE System.out.println(bb3); // FALSE } }
~Well, that's all for the functional interface