package com.java.design.java8; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.function.*; import java.util.stream.Collectors; /** * @author Chen Yang */ @RunWith(SpringRunner.class) @SpringBootTest public class FuncInterface {
I. understanding of functional programming
//Understanding of functional programming // //Functional interface programming is a further abstraction of business applications //In the class method definition, only functional interface needs to be implemented regardless of the logic of business implementation //Using Lambda expression to flexibly implement the business logic when the external application calls the business
II. Test method of functional interface
1. Function interface
// Function Function<Integer, Integer> sum = integer -> integer + 1; Function<Integer, Integer> multiply = integer -> integer * integer; List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0); public int testFunctionCompose(Integer integer) { return sum.compose(multiply).apply(integer); } public int testFunctionAndThen(Integer integer) { return sum.andThen(multiply).apply(integer); }
2. BiFunction interface
// BiFunction BiFunction<Integer, Integer, Integer> subtract = (first, last) -> first - last; public int testBiFunctionAndThen(Integer first, Integer last) { return subtract.andThen(multiply).apply(first, last); }
3. BinaryOperator interface
// BinaryOperator BinaryOperator<Integer> binaryOperator = (first, last) -> first - last; public int testBinaryOperator(Integer first, Integer last) { return binaryOperator.apply(first, last); } public String testMinBy(String first, String last, Comparator<String> comparator) { return BinaryOperator.minBy(comparator).apply(first, last); } public String testMaxBy(String first, String last, Comparator<String> comparator) { return BinaryOperator.maxBy(comparator).apply(first, last); }
//comparator //Compare the length of a string Comparator<String> length = (first, last) -> first.length() - last.length(); //Compare string initial ASCII size Comparator<String> asc = (first, last) -> first.charAt(0) - last.charAt(0);
4. Predict interface
// Predicate public List<Integer> testPredicate(Predicate<Integer> predicate) { return list.stream().filter(predicate).collect(Collectors.toList()); } public Predicate<String> isEqual(Object object) { return Predicate.isEqual(object); } public Predicate<Integer> notPredicate(Predicate<Integer> predicate) { return Predicate.not(predicate); } public List<Integer> testPredicateNegate(Predicate<Integer> predicate) { return list.stream().filter(predicate.negate()).collect(Collectors.toList()); } public List<Integer> testPredicateAnd(Predicate<Integer> first, Predicate<Integer> last) { return list.stream().filter(first.and(last)).collect(Collectors.toList()); } public List<Integer> testPredicateOr(Predicate<Integer> first, Predicate<Integer> last) { return list.stream().filter(first.or(last)).collect(Collectors.toList()); }
5. Supplier interface
// Supplier @Data @AllArgsConstructor @NoArgsConstructor private class Student { private Integer id; private String name; private String sex; private Integer age; private String addr; private Double salary; }
III. test results
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.1.2.RELEASE) 2019-01-31 11:51:58.460 INFO 12080 --- [ main] com.java.design.java8.FuncInterface : Starting FuncInterface on DESKTOP-87RMBG4 with PID 12080 (started by 46250 in E:\IdeaProjects\design) 2019-01-31 11:51:58.461 INFO 12080 --- [ main] com.java.design.java8.FuncInterface : No active profile set, falling back to default profiles: default 2019-01-31 11:51:58.988 INFO 12080 --- [ main] com.java.design.java8.FuncInterface : Started FuncInterface in 0.729 seconds (JVM running for 1.556) --------------------Understanding of Function interface--------------------- 65 81 ------------------Understanding of BiFunction interface--------------------- 64 -------------------Understanding of predict interface--------------------- Get a set that meets the criteria: greater than 4 [5, 6, 7, 8, 9] ------------------------------ Get the set satisfying the condition: greater than 4 and even [6, 8] ------------------------------ Get the set that meets the conditions: more than 4 negates [1, 2, 3, 4, 0] ------------------------------ Get the set that meets the condition: greater than 4 or even [2, 4, 5, 6, 7, 8, 9, 0] ------------------------------ Use the Equals method of Objects to determine whether the Objects are the same true ------------------------------ Predict. Not() returns (predict < T >) target. Gate(); [1, 2, 3, 4, 0] ------------------------------ Double negation for affirmation [5, 6, 7, 8, 9] ------------------------------ -------------------Understanding of Supplier interface--------------------- FuncInterface.Student(id=1, name=Kirito, sex=Male, age=18, addr=ShenZhen, salary=9.99999999E8) ------------------------------ ---------------Understanding of the BinaryOperator interface------------------- Implementation of subtraction by applying method inheriting BiFunction 10 - 2 = 8 ------------------------------ The short string is: Asuna The long string is: Kirito ------------------------------ String initial ASCII is smaller: Asuna The big one is: Kirito Process finished with exit code 0
4. See the source code implementation of the essential function interface through the phenomenon
1. Function interface
@Test public void testFuncInterface() { System.out.println("--------------------Function Interface understanding---------------------\n"); // Understanding of Function interface // public interface Function<T, R> // R apply(T t); // Represents a function that accepts one argument and produces a result. // A function: receive a parameter and return a result // T input type R output type /*default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v)); } * Returns a composed function that first applies the {@code before} * function to its input, and then applies this function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. */ // Input -- > beforefunction() processing -- > the result is used as the input parameter of the next function apply() to form a series call of the functional interface // beforeFunction is called before the current function is applied /*default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); } * Returns a composed function that first applies this function to * its input, and then applies the {@code after} function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. */ // Input -- > apply() process -- > get the result as the input parameter of the next function after.apply() to form a series call of the functional interface // afterFunction is called after the current function is applied /*static <T> Function<T, T> identity() { return t -> t; * Returns a function that always returns its input argument. }*/ // Always return input parameters // Conclusion: // Function 1. Compose (function2) execution order -- > beforefunction() --- > thisfunction() --- function2 -- > function1 // function1.andThen(function2) execution order -- > thisfunction() --- > afterfunction() --- function1 -- > function2 // The operation result of the previous function is the input parameter of the next function // To understand the operation time, you can compare @ Before and @ After in Junit System.out.println(this.testFunctionCompose(8)); System.out.println(this.testFunctionAndThen(8));
2. BiFunction interface
System.out.println("------------------BiFunction Interface understanding---------------------\n"); // Understanding of BiFunction interface // @FunctionalInterface // public interface BiFunction<T, U, R> { // R apply(T t, U u); // A function: receive two parameters and return a result /* 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)); } } */ // It can be proved that BiFunction does not have the compose method by using the counter evidence method (hint: parameters and return values) // Applying two parameters to BiFunction will only get one return value, which will be the parameter passed in as Function // biFunction.andthen(function) System.out.println(this.testBiFunctionAndThen(10, 2));
3. Predict interface
System.out.println("-------------------Predicate Interface understanding---------------------\n"); // public interface Predicate<T> { // Represents a predicate (boolean-valued function) of one argument. /* * Evaluates this predicate on the given argument. * * Receive a judgment to determine whether the expected condition is met and return true false * boolean test(T t); */ System.out.println("Get a set that meets the criteria: greater than 4"); System.out.println(this.testPredicate(in -> in > 4)); System.out.println("------------------------------\n"); /* * Returns a composed predicate that represents a short-circuiting logical * AND of this predicate and another. When evaluating the composed * predicate, if this predicate is {@code false}, then the {@code other} * predicate is not evaluated. * * Short circuit logic and calculation * default Predicate<T> and(Predicate<? super T> other) { * Objects.requireNonNull(other); * return (t) -> test(t) && other.test(t); }*/ System.out.println("Get the set satisfying the condition: greater than 4 and even"); System.out.println(this.testPredicateAnd(in -> in > 4, in -> in % 2 == 0)); System.out.println("------------------------------\n"); /* * Returns a predicate that represents the logical negation of this * predicate. * * Take inverse * default Predicate<T> negate() { * return (t) -> !test(t); * } */ System.out.println("Get the set that meets the conditions: more than 4 negates"); System.out.println(this.testPredicateNegate(in -> in > 4)); System.out.println("------------------------------\n"); /* * Returns a composed predicate that represents a short-circuiting logical * OR of this predicate and another. When evaluating the composed * predicate, if this predicate is {@code true}, then the {@code other} * predicate is not evaluated. * * Short circuit logic or calculation * default Predicate<T> or(Predicate<? super T> other) { * Objects.requireNonNull(other); * return (t) -> test(t) || other.test(t); * } */ System.out.println("Get the set that meets the condition: greater than 4 or even"); System.out.println(this.testPredicateOr(in -> in > 4, in -> in % 2 == 0)); System.out.println("------------------------------\n"); /* * Returns a predicate that tests if two arguments are equal according * to {@link Objects#equals(Object, Object)}. * * Judge whether two Objects are the same according to the equals method of Objects * static <T> Predicate<T> isEqual(Object targetRef) { * return (null == targetRef) * ? Objects::isNull * : object -> targetRef.equals(object); * } */ System.out.println("Use Objects Of Equals Method to judge whether the objects are the same"); System.out.println(this.isEqual("Kirito").test("Kirito")); System.out.println("------------------------------\n"); /* * Returns a predicate that is the negation of the supplied predicate. * This is accomplished by returning result of the calling * {@code target.negate()}. * * Returns the negation of the supplied predicate * @SuppressWarnings("unchecked") * static <T> Predicate<T> not(Predicate<? super T> target) { * Objects.requireNonNull(target); * return (Predicate<T>)target.negate(); * } * } */ System.out.println("Predicate.not()Return(Predicate<T>)target.negate(); "); System.out.println(testPredicate(this.notPredicate(integer -> integer > 4))); System.out.println("------------------------------\n"); System.out.println("Double negation for affirmation"); System.out.println(testPredicateNegate(this.notPredicate(integer -> integer > 4))); System.out.println("------------------------------\n");
4. Supplier interface
System.out.println("-------------------Supplier Interface understanding---------------------\n"); /* * Represents a supplier of results. * * public interface Supplier<T> { * T get(); * } */ // Constructor reference constructor interface instance // Using the Supplier interface Student class must have a construction method with or without parameters // Supplier<Student> studentSupplier = () -> new Student(); Supplier<Student> studentSupplier = Student::new; Student student = studentSupplier.get(); student.setId(1); student.setName("Kirito"); student.setSex("Male"); student.setAge(18); student.setSalary(999999999.0); student.setAddr("ShenZhen"); System.out.println(student); System.out.println("------------------------------\n");
5. BinaryOperator interface
System.out.println("---------------BinaryOperator Interface understanding-------------------\n"); /* * * public interface BinaryOperator<T> extends BiFunction<T,T,T> { * * Returns the smaller value between the two comparison parameters * public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) { * Objects.requireNonNull(comparator); * return (a, b) -> comparator.compare(a, b) <= 0 ? a : b; * } * * Returns the larger value between the two comparison parameters * public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) { * Objects.requireNonNull(comparator); * return (a, b) -> comparator.compare(a, b) >= 0 ? a : b; * } * } */ System.out.println("inherit BiFunction Of Apply Method implementation subtraction"); System.out.println("10 - 2 = "+this.testBinaryOperator(10, 2)); System.out.println("------------------------------\n"); System.out.println("The shorter string is:"+this.testMinBy("Kirito","Asuna",length)); System.out.println("The long string is:"+this.testMaxBy("Kirito","Asuna",length)); System.out.println("------------------------------\n"); System.out.println("String initial ASCII The smaller ones are:"+this.testMinBy("Kirito","Asuna",asc)); System.out.println("String initial ASCII The larger one is:"+this.testMaxBy("Kirito","Asuna",asc)); } }