博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java行为参数化(二)-Lambda表达式
阅读量:6984 次
发布时间:2019-06-27

本文共 3993 字,大约阅读时间需要 13 分钟。

二.行为参数化的Lambda形式 Java8在推出行为参数化的同时也提供了Lambda表达式,那么Lambda表达式是什么呢?为什么要用Lambda表达式呢?

在上一篇中我们写到的例子,就可以用Lambda来实现,我们一起来看看:

public class one
{ public static void main(String[] args){ one one = new one(); /*show(one::otherMethod ,"hello world");*/ show(n->{System.out.println(n);}, "hello Lambda"); } /*public void otherMethod(T t){ int i = 0; System.out.println(i + t.toString()); }*/ public static void show(Consumer
consumer,String text){ consumer.accept(text); }}复制代码

如果对注释有疑问的话,请看上一篇文章哦

那么我们在调用show方法时又和上一篇文章(也就是第一个注释处)不同,我们没有传入方法引用,而是传入了...好吧,这就是Lambda表达式,上面在调用show方法传入的第一个参数:n->{System.out.println(n);}  就是本章要讲的Lambda表达式,它由一个参数列表和方法体组成,参数列表和方法体由  ->  隔开,在这里我们用的还是Consumer接口,再上一章的Consumer接口源码中我们看到它的抽象方法accept中接受一个泛型参数,那么我们现在传入的Lambda表达式它的参数列表也是一个参数,然后在方法体中打印输出这个参数(如果n是引用型变量的话先调用toString()方法再输出)然后show方法接收这个Lambda表达式给了第一个形参Consumer consumer并在show方法中调用了consumer对象的accept方法。

那么为什么Lambda表达式可以传递给一个函数式接口的引用呢?

其实,Lambda表达式就是一个实现了函数式接口的匿名类对象,在上面的Lambda表达式中我们用 n->{System.out.println(n);} 这个Lambda表达式的时候就等于创建了一个匿名类对象实现了Consumer接口并重写了Consumer的accept方法,accept方法的内容就是Lambda表达式的方法体。

我们现在来说说Lambda表达式的书写规则:刚才说到它由一个参数列表和一个方法体组成并由  ->  隔开,参数列表由  ( ) 括起来,方法体由  { }   括起来,等等,明明上面的Lambda表达式没有用  ( )  括起来啊!嘿嘿,那是因为上面的Lambda表达式重写的accept方法只有一个参数,所以它只用传入一个参数。当Lambda表达式的参数列表只有一个参数时,那么  ( )  可以省略。并且Lambda表达式的方法体也可以不用  { }  括起来,而是用表达式代替。

就比如:

(m,n) -> {return m>n;} 可以用  (m,n) -> m>n  代替() -> {return "hello Lambda";}  可以用  () -> "hello Lambda"  代替复制代码

那么我们应该在哪里应用Lambda表达式呢? 就如上面代码所示,Lambda应该用在函数式接口上,当我们实现一个函数式接口的时候就可以用Lambda表达式 。

上面的代码也可以这样写:

public class one
{ public static void main(String[] args){ /*one one = new one();*/ /*show(one::otherMethod ,"hello world");*/ /*show(n->{System.out.println(n);}, "hello Lambda");*/ Consumer
consumer = (n)->{System.out.println(n);}; consumer.accept("hello Lambda"); } /*public void otherMethod(T t){ int i = 0; System.out.println(i + t.toString()); }*/ /*public static void show(Consumer
consumer,String text){ consumer.accept(text); }*/}复制代码

我将原来的代码全部注释,只写了一个Consumer引用并将一段Lambda表达式赋值给它,就等于是写了一类实现了Consumer接口并创建了对象,这个对象就是consumer,然后调用它的accept方法。

一定要注意Lambda表达式只能用于实现函数是接口,Java提供了很多函数式接口在上一章我有提到过,在最后我还说到了函数描述符,在设立我再写一遍:

函数式接口 函数描述符 Predict T -> boolean Consumer T -> void Function<T , R> T -> R Supplier () -> T

UnaryOperator
(T , T) -> TBinaryOperator
(T , T) -> TBiPredict
(L , R) -> booleanBiConsumer
(T , U) -> voidBiFunction
(T , U) -> R复制代码

以上是常用的几个函数式接口,那么我们能发现函数描述符的方法签名就是Lambda表达式的方法签名。函数描述符就是一种描述Lambda和函数式接口的签名。

细心的人去看了这些函数式接口的源码后可能会发现它们有一个共同点:它们的抽象方法没有抛出异常,也就是说这这些函数式接口中我们没有办法抛出异常,只能捕获。就像是我写一个读取文件内容的Lambda表达式的话只能向下面这样:

public class one
{ public static void main(String[] args){ Consumer
consumer = path -> {File file = new File(path); try { BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); } catch (FileNotFoundException e) { e.printStackTrace(); } }; }}复制代码

因为Consumer的accept方法并没有声明抛出FileNotFoundException异常,所以所有需要捕获或者抛出异常的地方只能捕获,不能抛出,但是我们常常在写代码的时候希望很多底层功能产生的异常不要在底层捕获,而是全部抛出,在最上层一并捕获并进行处理。这个时候我们就要定义自己的 函数式接口,就像上面的读取文件Lambda表达式,如果我们希望抛出异常的话,那么就要这样做:

首先定义一个函数式接口,并在抽象方法处声明抛出异常

import java.io.FileNotFoundException;@FunctionalInterfacepublic interface MyInterface {    public void read(String path) throws FileNotFoundException;}复制代码

然后在Lambda表达式里直接上代码,不需要声明 try{}catch(){} 块

public class one
{ public static void main(String[] args){ MyInterface myInterface = path -> {File file = new File(path); BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); }; }}复制代码

转载于:https://juejin.im/post/5c39aff8e51d4551ec609de5

你可能感兴趣的文章
阿里将在雄安新区设3家子公司:涉AI、蚂蚁金服和菜鸟;北航设立全国首个人工智能专业,与百度合作办学...
查看>>
Powershell指令集_2
查看>>
归并排序算法
查看>>
北京第一个公共云计算平台即将诞生
查看>>
5G频谱相争“兵戎相见”各相部署风起云涌
查看>>
安全自动化在于信任,而非技术
查看>>
缘何Square可以在移动支付领域上成功?
查看>>
云计算从“仰望星空”到“脚踏实地”
查看>>
台积电要造第一款7nm芯片 明年下半年可投产
查看>>
《逻辑与计算机设计基础(原书第5版)》——3.9 二进制加法器
查看>>
《中国人工智能学会通讯》——8.25 基于演化优化的生物网络配准
查看>>
飞鹤乳业CIO:移动化让企业品牌和消费者紧密连接
查看>>
当精准广告遇到大数据
查看>>
《机器人自动化:建模、仿真与控制》——2.3 仿真
查看>>
泰一指尚大数据应用成为第一批省级重点企业研究院
查看>>
预测未来 盘点大数据分析领域五大趋势
查看>>
教你编写Node.js中间件,实现服务端缓存
查看>>
又到中元节 应用宝教你如何打败各种鬼
查看>>
资源大集中 浪潮I9000刀片为国家税务总局打造全能型平台
查看>>
PC如何接管手机的双因子身份验证 靠的是英特尔的CPU
查看>>