深入理解 lambda表达式 与 函数式编程 函数式接口源码解析(二)

7次阅读

共计 10907 个字符,预计需要花费 28 分钟才能阅读完成。

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));

}

}

正文完
 0