内容简介:1、Function接口2、BiFunction接口3、BinaryOperator接口
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 陈杨 */ @RunWith(SpringRunner.class) @SpringBootTest public class FuncInterface {
一、函数式编程的理解
// 函数式编程的理解 // // 函数接口式编程 是 对 业务应用的进一步抽象 // 在类方法定义中 只需实现FunctionalInterface 而不管业务实现的逻辑 // 在外部应用 调用该业务时 使用Lambda表达式 灵活实现其业务逻辑
二、 函数式接口的测试方法
1、Function接口
// 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接口
// 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接口
// 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<String> length = (first, last) -> first.length() - last.length(); //比较字符串首字母ASCII码大小 Comparator<String> asc = (first, last) -> first.charAt(0) - last.charAt(0);
4、Predicate接口
// 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接口
// 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; }
三、测试结果
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: 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) --------------------Function接口的理解--------------------- 65 81 ------------------BiFunction接口的理解--------------------- 64 -------------------Predicate接口的理解--------------------- 获取满足条件的集合:大于4 [5, 6, 7, 8, 9] ------------------------------ 获取满足条件的集合:大于4且是偶数 [6, 8] ------------------------------ 获取满足条件的集合:大于4 取反 [1, 2, 3, 4, 0] ------------------------------ 获取满足条件的集合:大于4或是偶数 [2, 4, 5, 6, 7, 8, 9, 0] ------------------------------ 使用Objects的Equals方法判断对象是否相同 true ------------------------------ Predicate.not()返回(Predicate<T>)target.negate(); [1, 2, 3, 4, 0] ------------------------------ 双重否定表肯定 [5, 6, 7, 8, 9] ------------------------------ -------------------Supplier接口的理解--------------------- FuncInterface.Student(id=1, name=Kirito, sex=Male, age=18, addr=ShenZhen, salary=9.99999999E8) ------------------------------ ---------------BinaryOperator接口的理解------------------- 集成BiFunction的Apply方法 实现减法 10 - 2 = 8 ------------------------------ 字符串较短的是:Asuna 字符串较长的是:Kirito ------------------------------ 字符串首字母ASCII码较小的是:Asuna 字符串首字母ASCII码较大的是:Kirito Process finished with exit code 0
四、透过现象看本质 函数式接口的源码实现
1、Function接口
@Test public void testFuncInterface() { System.out.println("--------------------Function接口的理解---------------------\n"); // Function接口的理解 // public interface Function<T, R> // R apply(T t); // Represents a function that accepts one argument and produces a result. // 一个函数:接收一个参数 返回一个结果 // T 输入类型 R 输出类型 /*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. */ // 输入-->beforeFunction()处理-->得到结果作为下一个函数apply()的输入参数 形成函数式接口的串联调用 // beforeFunction 在当前函数apply前 进行调用 /*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. */ // 输入-->apply()处理-->得到结果作为下一个函数after.apply()的输入参数 形成函数式接口的串联调用 // afterFunction 在当前函数apply后 进行调用 /*static <T> Function<T, T> identity() { return t -> t; * Returns a function that always returns its input argument. }*/ // 总是返回输入参数 // 总结: // function1.compose(function2) 执行顺序 -->BeforeFunction()-->thisFunction()--> function2 --> function1 // function1.andThen(function2) 执行顺序 -->thisFunction()-->AfterFunction()--> function1 --> function2 // 前一个函数的运算结果 作为下一个函数的输入参数 // 理解运行时机 可以类比 Junit中 @Before 与 @After System.out.println(this.testFunctionCompose(8)); System.out.println(this.testFunctionAndThen(8));
2、BiFunction接口
System.out.println("------------------BiFunction接口的理解---------------------\n"); // BiFunction 接口 的 理解 // @FunctionalInterface // public interface BiFunction<T, U, R> { // R apply(T t, U u); // 一个函数:接收二个参数 返回一个结果 /* 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)); } } */ // 利用反证法 可以证明 BiFunction 没有 compose方法 (提示: 参数 与 返回值) // 将2个参数应用于BiFunction 只会得到一个返回值 这个返回值会作为Function传入的参数 // biFunction.andthen(function) System.out.println(this.testBiFunctionAndThen(10, 2));
3、Predicate接口
System.out.println("-------------------Predicate接口的理解---------------------\n"); // public interface Predicate<T> { // Represents a predicate (boolean-valued function) of one argument. /* * Evaluates this predicate on the given argument. * * 接收一个判断 判断是否满足预期条件 返回true false * boolean test(T t); */ System.out.println("获取满足条件的集合:大于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. * * 短路逻辑与计算 * default Predicate<T> and(Predicate<? super T> other) { * Objects.requireNonNull(other); * return (t) -> test(t) && other.test(t); }*/ System.out.println("获取满足条件的集合:大于4且是偶数"); 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. * * 取反 * default Predicate<T> negate() { * return (t) -> !test(t); * } */ System.out.println("获取满足条件的集合:大于4 取反"); 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. * * 短路逻辑或计算 * default Predicate<T> or(Predicate<? super T> other) { * Objects.requireNonNull(other); * return (t) -> test(t) || other.test(t); * } */ System.out.println("获取满足条件的集合:大于4或是偶数"); 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)}. * * 根据Objects的equals方法 来判断两个对象 是否相同 * static <T> Predicate<T> isEqual(Object targetRef) { * return (null == targetRef) * ? Objects::isNull * : object -> targetRef.equals(object); * } */ System.out.println("使用Objects的Equals方法判断对象是否相同"); 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()}. * * 返回提供的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()返回(Predicate<T>)target.negate(); "); System.out.println(testPredicate(this.notPredicate(integer -> integer > 4))); System.out.println("------------------------------\n"); System.out.println("双重否定表肯定"); System.out.println(testPredicateNegate(this.notPredicate(integer -> integer > 4))); System.out.println("------------------------------\n");
4、Supplier接口
System.out.println("-------------------Supplier接口的理解---------------------\n"); /* * Represents a supplier of results. * * public interface Supplier<T> { * T get(); * } */ // 构造方法引用 构造函数接口实例 // 利用Supplier接口 Student类必须要有无参的构造方法 // 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接口
System.out.println("---------------BinaryOperator接口的理解-------------------\n"); /* * * public interface BinaryOperator<T> extends BiFunction<T,T,T> { * * 返回2个比较参数之间的较小值 * public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) { * Objects.requireNonNull(comparator); * return (a, b) -> comparator.compare(a, b) <= 0 ? a : b; * } * * 返回2个比较参数之间的较大值 * 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("集成BiFunction的Apply方法 实现减法"); System.out.println("10 - 2 = "+this.testBinaryOperator(10, 2)); System.out.println("------------------------------\n"); System.out.println("字符串较短的是:"+this.testMinBy("Kirito","Asuna",length)); System.out.println("字符串较长的是:"+this.testMaxBy("Kirito","Asuna",length)); System.out.println("------------------------------\n"); System.out.println("字符串首字母ASCII码较小的是:"+this.testMinBy("Kirito","Asuna",asc)); System.out.println("字符串首字母ASCII码较大的是:"+this.testMaxBy("Kirito","Asuna",asc)); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 【译】函数声明 VS 函数表达式
- 函数声明?函数表达式?我该怎么选?!
- JavaScript(js)函数声明与函数表达式的区别
- ECMAScript学习笔记(八)——函数表达式
- 函数式编程1-Lambda表达式
- Java 函数式编程(二)Lambda表达式
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。