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));
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。