Lambda表达式的作用:

  Lambda表达式的作用就是简化代码开发,让代码看起来更加简介。它是用来简化匿名内部类的。但是并不是所有的匿名内部类都能用Lambda表达式简化,Lambda表达式是有使用前提的。

Lambda表达式的使用前提:

  1、用Lambda表达式简化的这个匿名内部类必须是某一个接口的实现类,且这个实现的接口中有且只有一个抽象方法;因为只有这样,Lambda才能够根据接口中的上下文(代码)来推断出你简化的地方是什么内容,下面就来实际演示一下。(注:有且只有一个抽象方法的接口称为“函数式接口”)

  2、使用Lambda表达式的地方必须具有上下文推断,就是在使用Lambda表达式的地方知道能够通过代码上下文推断出所需要的信息,因为Lambda表达式简化匿名内部类是不会写出匿名内部类实现所实现的接口,所以需要在能够推测出接口的地方使用(有点抽象,可以通过下面的案例来理解)。

Lambda表达式的格式:

  Lambda表达式主要由三部分构成:()->{ }

    1、开头小括号开始 ( ) :小括号中填写的是重写接口中的方法时,方法的参数。若方法无参数,则小括号空着,若有多个参数,则参数间用逗号隔开(与普通Java方法相同)

    2、中间一个箭头 ->:可以理解为将参数传入到方法体中;

    3、末尾一个大括号{ }:大括号中的内容就是方法体,也就是方法的逻辑代码;

  当然,上面的结构是标准结构,但却不是绝对的,在某些情况下,部分内容可以省略,在下面的案例中将进行详细讲解。

Lambda使用案例:

  案例一:Lambda表达式简化匿名内部类,重写无参数无返回值方法

  首先,我们创建一个接口,用来测试Lambda表达式。通过Lambda表达式的使用前提可知,这个接口应当有且只有一个抽象方法。接口名字叫Test,方法叫display():

 public interface Test {

     public abstract void display();

 }

  然后,我们创建一个类,这个类中有一个方法useDisplay(Test t),它唯一的参数就是上面定义的接口Test。我们知道,当要调用这个方法时,应当传入一个Test接口的实现类,方法代码如下:

 public static void useDisplay(Test t) {
//方法的内容就是调用接口中的display方法
t.display();
}

  接下来,我们调用这个方法,分别采用匿名内部类以及Lambda表达式两种方式,以此来进行对比:

 //调用方法,接口参数使用匿名内部类当场实现
useDisplay(
new Test() {
//重写接口中的方法,输出一句话
@Override
public void display() {
System.out.println("Lambda表达式案例一");
}
}
);

  上面的代码调用了useDisplay(Test t)方法,并在括号中使用匿名内部类实现了Test接口以及重写了Test的方法,将匿名内部类作为参数传递。这是匿名内部类的方式,那下面看看Lambda表达式时怎么去写的:

 useDisplay(
//使用Lambda实现
()->{
System.out.println("Lambda表达式案例一");
}
);

  可以看到,代码明显精简了许多,我们来仔细看看究竟做了哪些改变:我们省略new,也省略了接口的名字,直接重写接口中的方法。为什么可以这么做呢,这就关系到我们之前所说的Lambda使用前提2:使用Lambda表达式的地方必须具有上下文推断;Lambda知道useDisplay的参数是Test接口,所有Lambda知道这里应该实现的接口就是Test,不可能是其他的了,因此可以省略接口名。接下来省略了方法的public、返回值类型、方法名,这些Lambda也可以推断出来,因为已经确定了是Test接口,那自然也知道了这个接口中的方法display()的信息,所以统统可以省略,这也是Lambda表达式使用前提1的原因。

  然而,上面的Lambda表达式只是标准格式,它还能够继续简化,上面的表达式简化后的如下:

 useDisplay(  ()->System.out.println("Lambda表达式案例一") /*此处原本有分号*/ );

  可以看到,上面的Lambda表达式相对于之前,省略了大括号以及末尾的分号。只有在Lambda表达式的方法体,也就是大括号中只有一条语句时,才能够省略大括号,同时也要省略分号,两者要么一起省略,要么都不省略。

  案例二:Lambda表达式简化匿名内部类,重写有参有返回值方法

  同样是定义一个接口Calculator,里面只有一个抽象方法add(),计算两个整数的和:

 public interface Calculator {

     public abstract int add(int a,int b);

 }

  与上一个案例类似的结构,在另一个类中定义一个方法invokeAdd,方法的内容就是调用接口中的add方法,得到两个整数的和并输出:

 public static void invokeAdd(int a,int b,Calculator cal) {
System.out.println(cal.add(a, b));
}

  首先还是和第一个案例一样,我们使用匿名内部类的方式调用这个方法(这次我把代码写的紧凑一些,上一个案例代码都拉的很开,方便查看):

 invokeAdd(10, 20, new Calculator() {
@Override
public int add(int a, int b) {
return a+b;
}
});

  上面代码很简单,传入两个要相加的整数10和20,以及一个匿名内部类对象实现,实现Calculator接口,重写接口中add方法,求两个整数的和。下面来看看Lambda表达式怎么写上面这个代码:

 //使用Lambda表达式的方式代替匿名内部类实现
invokeAdd(10, 20, (int a,int b)->{
return a+b;
});

  还是来看看改变了哪些内容:首先,这是比较标准的写法,与案例一相同,省略了接口,直接重写接口中的方法,然后省略了方法的名字类型等,只留下一个大括号,里面包含方法的参数,后面跟着一个箭头,指向了方法体,而方法体则未改变。但是,这并不是最简略的写法,看下面这种更加简洁的写法:

 //上Lambda表达式的简化
invokeAdd(10, 20, (a,b) -> a+b );

  可以看到,这时已经简化到只剩一句代码了,我们来仔细看看简化了哪些内容:首先,填写方法参数的小括号中,参数的类型省略了,还是和上面一样的原因,既然Lambda表达式已经知道了你实现的接口,就知道了接口中那唯一的方法,也就知道了方法中参数的类型,所以即使你省略,Lambda也能够根据上下文推测出来;其次,因为方法体中只有一句代码,所以可以省略大括号以及方法体中语句末尾的分号;除此之外,这是一个有返回值的方法,在方法体中只有一句代码的情况下,连return这个关键字都能省略。(注意:大括号,逗号,return关键字,要么一起省略,要么都不省略。)

  最后再说一个可以简化Lambda表达式的情况,就是当接口中的方法只有一个参数时,连填写参数的小括号都可以省略,这里就不演示了。

快速掌握Java中Lambda表达式的用法的更多相关文章

  1. Java中lambda表达式详解

    原文地址:http://blog.laofu.online/2018/04/20/java-lambda/ 为什么使用lambda 在java中我们很容易将一个变量赋值,比如int a =0;int ...

  2. Java中Lambda表达式的使用

    简介(译者注:虽然看着很先进,其实Lambda表达式的本质只是一个"语法糖",由编译器推断并帮你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能.本人建议不要乱用,因 ...

  3. Java中Lambda表达式的使用(转)

    https://www.cnblogs.com/franson-2016/p/5593080.html 简介(译者注:虽然看着很先进,其实Lambda表达式的本质只是一个"语法糖" ...

  4. Java中Lambda表达式的简单使用

    Lambda表达式是Java SE 8中一个重要的新特性.你可以把 Lambda表达式 理解为是一段可以传递的代码 (将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码风格 ...

  5. Java中lambda(λ)表达式的语法

    举一个排序的例子,我们传入代码来检查一个字符串是否比另一个字符串短.这里要计算: first.length() - second.length() first和second是什么?他们都是字符串.Ja ...

  6. 为什么Java中lambda表达式不能改变外部变量的值,也不能定义自己的同名的本地变量呢?

    作者:blindpirate链接:https://www.zhihu.com/question/361639494/answer/948286842来源:知乎著作权归作者所有.商业转载请联系作者获得授 ...

  7. Java中Lambda表达式基础及使用详解

    概述 Lambda 是JDK 8 的重要新特性.它允许把函数作为一个方法的参数(函数作为参数传递进方法中),使用 Lambda 表达式可以使代码变的更加简洁紧凑,使Java代码更加优雅. 标准格式 三 ...

  8. Java中lambda表达式学习

    一.Lambda表达式的基础语法: Java8中引入了一个新的操作符"->"该操作符称为箭头操作符或Lambda操作符,箭头操作符将Lambda表达式拆分为两部分: 左侧:L ...

  9. Java中Lambda表达式的进化之路

    Lambda表达式的进化之路 为什么要使用Lambda表达式 可以简洁代码,提高代码的可读性 可以避免匿名内部类定义过多导致逻辑紊乱 在原先实现接口抽象方法的时候,需要通过定义一个实现接口的外部类来实 ...

随机推荐

  1. PCA原理(转)

    PCA(Principal Component Analysis)是一种常用的数据分析方法.PCA通过线性变换将原始数据变换为一组各维度线性无关的表示,可用于提取数据的主要特征分量,常用于高维数据的降 ...

  2. etcd ui

    https://github.com/henszey/etcd-browser docker build --build-arg http_proxy=http://109.105.4.17:3128 ...

  3. TOMCAT下面发布项目的4种方式

    摘要 TOMCAT下面发布项目的4种方式,可用于在平时资料查询. 第一种方法: 将web项目文件件拷贝到webapps 目录中:或者直接通过Eclipse发布到Tomcat上. 第二种方法: 在tom ...

  4. 实例学习SSIS(一)

    网址: http://www.cnblogs.com/tenghoo/archive/2009/10/archive/2009/10/archive/2009/10/archive/2009/10/a ...

  5. webpack 常用插件及作用

    copy-webpack-plugin :复制文件到目标文件夹.在开发时使用热模替换,(没有生成dist 文件夹,都在内存中),如果想引用某一个js文件,直接写script标签是找不到的,因为服务器内 ...

  6. PIE结对项目编程

    一.题目描述 构造程序并测试,分别是:     1.不能触发Fault.     2.触发Fault,但是不能触发Error.     3.触发Error,但是不能产生Failure. 二.结对对象 ...

  7. Java的Reflection机制

    什么时候使用Reflection: 在java语言中,创建一个类的对象通常使用new operator,但是如果预先不知道Class的名字,类名是在程序运行过程中通过参数传递过来,就没法使用这种方法了 ...

  8. FileUpload控件实现单按钮图片自动上传并带预览显示

    FileUpload控件实现单按钮图片自动上传并带预览显示 1.实现原理:   FileUpload控件默认不支持服务端的ONCHANGE事件,此时用一种变通的方法借用客户端的onchange事件,调 ...

  9. 关于Python的OSError和IOError

    参考:http://stackoverflow.com/questions/29347790/difference-between-ioerror-and-oserror 在3.x版本已经移除,剩下O ...

  10. Python调shell

    os.system(cmd) 函数返回cmd的结束状态码,阻塞调用. os.popen(cmd) 函数返回cmd的标准输出,阻塞调用. (status, output) = commands.gets ...