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

栏目: 编程语言 · 发布时间: 7年前

内容简介: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));

    }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Sprint

Sprint

Jake Knapp、John Zeratsky、Braden Kowitz / Simon & Schuster / 2016-3-8 / GBP 14.60

媒体推荐 “Every business leader I know worries about the same thing: Are we moving fast enough? The genius of Jake Knapp’s Sprint is its step-by-step breakdown of what it takes to solve big problems an......一起来看看 《Sprint》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

MD5 加密
MD5 加密

MD5 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具