Lambda表达式

简介: 主要介绍Lambda表达式

1.概述


Lambda表达式是JDK8开始后的一种新语法形式,其作用为简化匿名内部类的代码写法。


1.1 Lambda表达式的语法


Lambda表达式由三部分组成:

基本语法: (parameters) -> expression 或 (parameters) ->{ statements; }

1.paramaters:类似方法中的形参列表,这里的参数是函数式接口里的参数。

2.->:可理解为“被用于”的意思。

3.方法体:可以是表达式也可以是代码块,是函数式接口里方法的实现。


以下为一些示例:


//1.不需要参数,返回值为2
()->2
//2.接收一个参数(数字类型),返回其二倍的值
x->2*x
//3.接收2个参数(数字),并返回他们的和
(x,y)->x+y
//4.接收2个int型整数,返回他们的乘积
(int x,int y)->x*y
//5.接收一个string对象,并在控制台下打印,不返回任何值(看起来像是返回void)
(String s)->System.out.print(s)


1.2 函数式接口


在了解lambda表达式之前,需要先理解什么是函数式接口,函数式接口定义:一个接口有且仅有一个抽象方法

(注意:函数式接口还需要声明@FunctionalInterface注解,这样编译器将会自动进行检测该函数式接口是否只有一个抽象方法)


如下实例:


@FunctionalInterface
interface NoParameterNoReturn { 
  //注意:只能有一个方法 
  void test(); 
}

2.Lambda表达式的基本使用


我们首先来准备几个接口:


//无返回值无参数
@FunctionalInterface
interface NoParameterNoReturn {
    void test();
}
//无返回值一个参数
@FunctionalInterface
interface OneParameterNoReturn {
    void test(int a);
}
//无返回值多个参数
@FunctionalInterface
interface MoreParameterNoReturn {
    void test(int a,int b);
}
//有返回值无参数
@FunctionalInterface
interface NoParameterReturn {
    int test();
}
//有返回值一个参数
@FunctionalInterface
interface OneParameterReturn {
    int test(int a);
}
//有返回值多参数
@FunctionalInterface
interface MoreParameterReturn {
    int test(int a,int b);
}


Lambda表达式的作用是为简化匿名内部类的代码写法,实际上是创建了一个类,实现了接口,重写了接口的抽象方法(接口不能实例化,所以相当于实例化了一个匿名内部类)。


在没有使用Lambda表达式的时候的调用方式:


NoParameterNoReturn noParameterNoReturn=new NoParameterNoReturn() {
      @Override
      public void test() {
           System.out.println("hello");
      }
};
noParameterNoReturn.test();


使用Lambda表达式后:


public class lambda {
    public static void main(String[] args) {
        NoParameterNoReturn noParameterNoReturn=()->System.out.println("无参数返回值");
        noParameterNoReturn.test();
        OneParameterNoReturn oneParameterNoReturn=(int a)->System.out.println("一个参数无返回值:"+a);
        oneParameterNoReturn.test(10);
        MoreParameterNoReturn moreParameterNoReturn=(int a,int b)->System.out.println("多个参数无返回值:"+a+" "+b);
        moreParameterNoReturn.test(20,30);
        NoParameterReturn noParameterReturn=()->{
            System.out.println("有返回值无参数");
            return 0;
        };
        int ret=noParameterReturn.test();
        System.out.println(ret);
        OneParameterReturn oneParameterReturn=(int a)->{
            System.out.println("有返回值有一个参数");
            return a;
        };
        ret=oneParameterReturn.test(50);
        System.out.println(ret);
        MoreParameterReturn moreParameterReturn=(int a,int b)->{
            System.out.println("有返回值有多个参数");
            return a+b;
        };
        ret= moreParameterReturn.test(30,40);
        System.out.println(ret);
    }
}


语法精简规则:


参数类型可以省略,如果需要省略,每个参数的类型都要省略。

参数的小括号里面只有一个参数,那么小括号可以省略

如果方法体当中只有一句代码,那么大括号可以省略

如果方法体中只有一条语句,其是return语句,那么大括号可以省略,且去掉return关键字。


3.变量捕获


3.1 匿名内部类的变量捕获


class Test {
    public void func(){
        System.out.println("func()");
    }
}
public class Demo {
    public static void main(String[] args) {
        int a=100;
        new Test(){
            @Override
            public void func() {
                System.out.println("我是内部类,且重写了func这个方法!");
                System.out.println("捕获到变量a=="+a);
            }
        };
    }
}


在上述代码中的变量a就是捕获的变量。这个变量要么是被final修饰,如果不被final修饰需要确保在使用之前没有被修改。如下便是错误代码:


public class Demo {
    public static void main(String[] args) {
        int a=100;
        new Test(){
            @Override
            public void func() {
              a=99;
                System.out.println("我是内部类,且重写了func这个方法!");
                System.out.println("捕获到变量a=="+a);
            }
        };
    }
}


该代码直接编译报错。


3.2 Lambda的变量捕获


@FunctionalInterface
interface NoParameterNoReturn {
    void test();
}
public static void main(String[] args) {
    int a=10;
    NoParameterNoReturn noParameterNoReturn=()->{
      //a=99;  error
        System.out.println("捕获变量:"+a);
    };
    noParameterNoReturn.test();
}

4.总结


接口并不能直接实例化,但可以通过匿名内部类(实现该接口的匿名类)来不借助类去实现接口中的方法,但Lambda表达式是匿名内部类的更进一步,它可以直接实现接口中的方法(不需要借助类,也不需要重写抽象方法)。

Lambda表达式的优点很明显,在代码层次上来说,使代码变得非常的简洁。缺点也很明显,代码不易读


优点:


1.代码简洁,开发迅速

2.方便函数式编程

3.非常容易进行并行计算

4.Java中引入了Lambda,改善了集合操作


缺点:


1.代码可读性变差

2.在非并行计算中,很多计算未必有传统的for性能高

3.不容易进行调试


相关文章
|
11月前
|
监控 测试技术 开发者
一行代码改进:Logtail的多行日志采集性能提升7倍的奥秘
一个有趣的现象引起了作者的注意:当启用行首正则表达式处理多行日志时,采集性能出现下降。究竟是什么因素导致了这种现象?本文将探索Logtail多行日志采集性能提升的秘密。
522 57
|
监控 网络协议 应用服务中间件
深入解析:如何确定网站使用的端口号
【10月更文挑战第21天】 在网络通信中,端口号是识别特定服务的关键。一个IP地址可以有多个端口,每个端口可能运行着不同的服务。当我们在浏览器地址栏输入一个网址时,实际上是通过特定的端口与服务器进行通信。本文将探讨如何确定一个网站使用的端口号,以及端口号在网络通信中的作用。
1142 4
GrayLog5.2版本单节点一键部署脚本
GrayLog5.2版本单节点一键部署脚本
684 0
|
NoSQL 物联网 atlas
浅析通过MongoDB一起解锁工业4.0转型的无限潜力!
MongoDB在智能制造中发挥关键作用,通过其开发者数据平台提升工业4.0的潜能,实现生产效率的提高和成本降低。借助MongoDB Atlas,企业能实时洞察、增强整体设备效率,构建现代物联网应用。MongoDB助力企业数字化转型,通过西门子数字化工厂、RideKleen、Longbow Advantage和博世数字等案例展示了其在提高生产灵活性、保障高可用性、加速创新和实现无缝数据同步方面的优势。MongoDB使制造企业能够应对数据挑战,优化运营,提升客户体验。
|
分布式计算 数据挖掘 数据处理
Spark如何支持实时数据分析?
【6月更文挑战第16天】Spark如何支持实时数据分析?
315 3
|
网络协议 Linux Windows
TCP/IP、Http、Socket之间的区别
TCP/IP、Http、Socket之间的区别
684 3
|
SQL 安全 算法
带你读《代码管理实践10讲》——七、3类代码安全风险如何避免?
带你读《代码管理实践10讲》——七、3类代码安全风险如何避免?
337 0
|
机器学习/深度学习 算法 数据可视化
YOLO+混合注意力机制 | YOLOv5再加4.3%才可以做对手,Transformer混合设计依旧可以卷
YOLO+混合注意力机制 | YOLOv5再加4.3%才可以做对手,Transformer混合设计依旧可以卷
481 0
|
Cloud Native 搜索推荐 应用服务中间件
云原生之使用Docker部署h5ai文件展示页
云原生之使用Docker部署h5ai文件展示页
355 2