• Java8 函数式编程【基础篇】


            Java 8是Java在保持向后兼容的前提下首次迈出重要一步,相比之前,不再是只对类库的改良,在编写复杂的集合处理、并行化执行、代码简洁度等方面都有颠覆性的提升。本文将探索和理解函数式编程的含义,以及它在Java 8中的实现。

    一、理解函数式编程

            Java倡导“一切皆对象”,面向对象编程(OOP)是对数据进行抽象,主要抽象类/对象,是命令式编程风格。而函数式编程(OOF)是对行为进行抽象,主要是抽象函数,是声明式编程风格,其核心是:在思考问题时,使用不可变值和函数,函数对一个值进行处理,映射成另一个值。

    二、Java 8 为实现函数式编程提供的支持

    1、Lambda表达式

    定义:本质上是一段匿名内部类,也可以是一段可以传递的代码(将代码像数据一样进行传递)。

    作用:使代码更简洁、更灵活、更紧凑。

    语法:()->();

    口诀:左右遇一省括号,左侧推断类型省

    1. /** case1-表达式不包含参数 */
    2. Runnable noArguments = () -> System.out.println("Hello Word");
    3. /** case2-表达式只有一个参数 */
    4. Consumer tConsumer = evnet -> System.out.println("Hello Word");
    5. /** case3-表达式的主体是一段代码块 */
    6. Runnable multiStatement = () -> {
    7. System.out.printf("Hello");
    8. System.out.println(" Word");
    9. };
    10. /** case4-表达式有多个参数 */
    11. BinaryOperator<Long> addFun = (x, y) -> x + y;
    12. /** case5-显示声明表达式参数类型,而非编译器推断 */
    13. BinaryOperator<Long> addExplicit = (Long x, Long y) -> x + y;

    2、引用

    作用:是Lambda表达式的另外一种表现形式,且语法比Lambda表达式更加简单

    类型:

    • 方法引用[对象-实例方法、类-静态方法、类-实例方法]:ClassName::monthod

    • 构造器引用:ClassName::new

    • 数组引用:Type[]::new

    1. /** 方法引用-ClassName::monthod */
    2. Consumer<String> consumer = System.out::println;
    3. // 方法引用-类名::静态方法名
    4. BiFunction<Integer, Integer, Integer> biFunction = Integer::compare;
    5. biFunction.apply(10, 20);
    6. // 方法引用-类名::实例方法名
    7. BiFunction<String, String, Boolean> booleanBiFunction = String::equals;
    8. booleanBiFunction.apply("hello", "hello");
    9. /** 构造器引用:ClassName::new */
    10. Supplier<LambdaDemo> supplier = LambdaDemo::new;
    11. /** 数组引用 Type[]::new */
    12. Function<Integer, String[]> function = String[]::new;
    13. function.apply(10);

    3、类型推断

            在Lambda 表达式中无需指定类型,程序依然可以编译,由编译器根据程序的上下文推断出来,这就是所谓的“类型推断”。实际上是Java 7中引入的目标类型推断(菱形操作符)的扩展。

    4、函数式接口

    定义:函数接口是只有一个抽象方法的接口,使用只有一个方法的接口来表示某特定方法并反复使用,是一种表示函数的方式。任何需要函数式接口的地方,我们都可以使用Lambda表达式(或方法引用)。

    作用:为了给Lambda表达式的使用提供更好的支持,不需要自己再手动创建一个函数式接口,直接拿来用就好了。

    使用:

    • 自定义函数式接口:在接口上标注@FunctionalInterface 注解。

    • java.util.function包下定义了Java 8提供的函数式接口,可直接使用。

    1. /**
    2. * 核心函数式接口
    3. */
    4. // Consumer
    5. Consumer<String> consumer = str -> System.out.println(str);
    6. consumer.accept("Consumer-消费型,有入参无返回");
    7. // Supplier
    8. Supplier<String> supplier = () -> "Supplier-供给型,无入参有返回";
    9. System.out.println(supplier.get());
    10. // Function
    11. Function<Integer, String> function = integer -> {
    12. if (integer > 0) {
    13. return "入参大于0";
    14. }
    15. return "入参小于等于0";
    16. };
    17. System.out.println("Function-函数市接口,有入参有返回" + function.apply(-10));
    18. // Predicate
    19. Predicate<Integer> predicate = integer -> integer < 10;
    20. System.out.println("Predicate-断言型接口,有入参有返回" + predicate.test(20));
    21. /**
    22. * 扩展函数式接口
    23. */
    24. // BiFunction
    25. BiFunction<Integer, Integer, Integer> biFunction = (x, y) -> x * y;
    26. biFunction.apply(2, 2);
    类型函数式接口方法
    四大核心函数式接口

    Consumer

    消费型接口

    void accept

    Supplier

    供给型接口

    T get()

    Function

    函数型接口

    R apply(T t)

    Predicate

    断言型接口

    boolean test(T t)
    Consumer-扩展函数式接口

    DoubleConsumer

    LongConsumer

    IntConsumer

    void accept(double value)

    void accept(long value)

    void accept(int value)

    ObjDoubleConsumer

    ObjLongConsumer

    ObjIntConsumer

    void accept(T t, double value)

    void accept(T t, long value)

    void accept(T t, int value)

    Supplier-扩展函数式接口

    BooleanSupplier

    DoubleSupplier

    LongSupplier

    IntSupplier

    boolean getAsBoolean()

    double getAsDouble()

    long getAsLong()

    int getAsInt()

    Function-扩展函数式接口BiFunctionR apply(T t, U u)

    DoubleFunction

    LongFunction

    IntFunction

    R apply(double value)

    R apply(long value)

    R apply(int value)

    ToDoubleFunction

    ToLongFunction

    ToIntFunction

    double applyAsDouble(T value)

    long applyAsLong(T value)

    int applyAsInt(T value)

    ToDoubleBiFunction

    ToLongBiFunction

    ToIntBiFunction

    double applyAsDouble(T t, U u)

    long applyAsLong(T t, U u)

    int applyAsInt(T t, U u)

    DoubleToIntFunction

    DoubleToLongFunction

    int applyAsInt(double value)

    long applyAsLong(double value)

    LongToDoubleFunction

    LongToIntFunction

    double applyAsDouble(long value)

    int applyAsInt(long value)

    IntToDoubleFunction

    IntToLongFunction

    double applyAsDouble(int value)

    long applyAsLong(int value)

    Predicate-扩展函数式接口BiPredicateboolean test(T t, U u)

    DoublePredicate

    LongPredicate

    IntPredicate

    boolean test(double value)

    boolean test(long value)

    boolean test(int value)

    -------------------------------------------------------------------------------------------------------------------------------

  • 相关阅读:
    如何在spark中使用scikit-learn和tensorflow等第三方python包
    想去银行测试?那这套题目你必须要会
    并购交易:埃克森美孚商谈以250美元/股的价格收购先锋自然资源
    反转链表(力扣)
    C++ 类成员 有静态成员, 5只猫咪总体重。
    22.10.31补卡 22CCPC桂林C题
    read系统调用源码分析
    Android PackageManager 基本使用
    云原生Spark UI Service在腾讯云云原生数据湖产品DLC的实践
    FlyFish开发者说|开源低代码平台的体验与思考
  • 原文地址:https://blog.csdn.net/qq_35808136/article/details/128128753