• 初识Java语言中的lambda表达式和函数式接口


    1. lambda表达式

    1.1 概述

    简单说来,lambda表达式实际上可以理解为一段代码,一段定义了但是却可以按需执行的代码。

    1.2 可能好的方面

    第一、lambda表达式的功能特性可以帮助java语言做到函数式编程,便于抽象和重构代码。
    第二、lambda表达式可以被定义为变量在代码中像传递普通变量一样进行传递,按照实际需要进行一次或者多次执行。
    第三、与函数式接口联合使用的时候,使用lambda表达式可以简化代码,代码写起来更加简洁。

    1.3 可能要注意

    第一、lambda表达式不同于一般的代码形式,一般的代码是写了后,如果代码走到了,里面的代码就会执行,而lambda表达式中的逻辑要被执行的话,还需要额外的一个调用动作。
    第二、使用lambda表达式的时候,要注意在lambda表达式中访问不同作用域下的变量的值的安全性,同时异常的处理以及日志记录等要注意。
    第三、使用lambda表达式因为简洁,所以有的时候使用过多会带来高度的抽象,可能会导致代码反而不易理解。比如 lambda表达式的参数和返回值的类型都是可以自动推导出来的。当然入参可以加注解让代码清晰点。但是还有各种泛型场景,这样看起来就不是那么明确清晰。

    2. 函数式接口

    2.1 概述

    满足以下2个条件就可以认为是函数式接口:
    条件1:是一个接口(interface);
    条件2:该接口中抽象方法只有一个。

    2.2 可能好的方面

    第一、函数式接口的对象,可以通过lambda表达式进行创建,而不用复杂的实现接口的类或者冗长的匿名类。
    第二、jdk中自带的函数式接口丰富在java.util.function下很多,使用很方便。
    第三、通过lambda表达式和函数式接口的综合使用,便于针对代码具备一定规律行为的抽象,提升代码的层次感。

    2.3 可能要注意

    第一、如果一个interface中有好几个方法,它有可能是函数式接口,只要它的方法中只有一个未实现的方法即可。例如:

    package lambda;
    
    public interface MultiMethodFunctionInterface {
        String getDisplayName();
    
        public default String getName() {
            return "---";
        }
        public  static void doSth()
        {
            System.out.println("I am doing something.");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    第二、函数式接口为了明确,我们可以在自定义的函数式接口定义处加上对应的@functionalinterface注解

    第三、函数式接口中的抽象方法的参数,尽量控制在3个以内,参数太多的使用起来容易引起理解的复杂性。如果参数就是比较多的话,建议使用类似POJO类的形式把参数进行合理的类定义,以此减少参数的个数。

    3. lambda表达式调用形式

    3.1 方法引用或构造方法引用

    2种形式:
    形式1:e -> String.valueOf(e);
    形式2: String::valueOf
    其中双冒号::的操作符会有几种常见形式:
    对象::对象的示例方法
    类::类的静态方法
    类::new
    this::方法
    super::方法

    3.2 lambda表达式中作用域的问题

    lambda表达式是一段代码,这段代码会包括3个部分,
    第一,自己独立的代码,
    第二,方法的参数,
    第三,该lambda表达式所能访问的自由的变量。
    关于最后一点,要特别重视,容易在多并发的场景引起问题。因此有个重要的的约束,虽然编译器会有一定的控制,但是注意不能完全检查的出来的,lambda表达式中被引用的自由的变量的值在lambda表达式中是不能被修改的,或者说编码者应该确保被引用的变量可以认为是自动带了final的修饰,然后即使这样还是有些很隐晦的编译器检查不出来,比如List的变量,在lambda表达式中改它里面的元素也是多线程不安全的。
    因此,对于lambda表达式在多线程的场景下,为了线程安全,尽量避免在lambda表达式中调用类的成员变量,类的静态变量等。

  • 相关阅读:
    libstdc++.so.6: cannot open shared object file: No such file or directory
    Java——数组的使用
    自动化测试类型有哪些?是怎么分类的
    快速批量升级 NugetPackage 版本
    Django--29用户权限设计
    正则表达式“~= s,/,\\,g“作用
    docker常用操作命令
    QT:QML中使用Loader加载界面
    csv2mind csv文件根据指定字段输出脑图统计
    【BOOST C++ 13 并行编程】(3) Futures和 Promises线程
  • 原文地址:https://blog.csdn.net/WolfOfSiberian/article/details/127132850