Java8之——简洁优雅的Lambda表达式
Java8发布之后,Lambda表达式,Stream等等之类的字眼边慢慢出现在我们字眼。就像是Java7出现了之后,大家看到了“钻石语法”,看到了try-with-resource等等。面对这些新东西,如果它能为我们提供方便带来不一样的改变。那么就值得去尝尝鲜。Java8出现了之后,我就扫了一眼新东西。但是实际工作中普遍使用的是Jdk1.7,1,6。所以就一直“闲置”了。而今闲了就看看。
Lambda表达式是怎样的?
下面将通过代码的形式来演示Lambda表达式,需要先安装JDK8.如果开发工具使用的是eclipse或者myeclipse的话,还需注意IDE的版本。版本低的还不支持Java8。
Lambda表达式如何创建一个线程?
我们知道创建线程有两种方式:
1.写一个类继承自Thread类,并实现run方法。然后,调用子类的start()方法启动线程。
2.实现Runable接口,并在run方法中写具体实现。将Runable的实现类 当做参数传递给Thread类的构造函数完成线程的创建。
第二种方法的实现写法可以如下:
例1-1
Thread sayHello=new Thread(new Runnable() { @Override public void run() { System.out.println("hello"); } }); sayHello.start();
上面代码很简单,Thread构造函数中接收了一个匿名函数。匿名函数返回的是一个Runnable接口实现。启动线程之后,将会输出:hello信息。
上面例1-1 中的代码如果换成lambda表达式书写的话,就会是下面这个样子:
例1-2
Thread thread=new Thread(()-> System.out.println("hello")); thread.start();
只有两行!怎么样?这一点有没有吸引到你。比起例1-1中的代码,例1-2更简洁,一目了然。这些改变就在于这一行代码:
()-> System.out.println("hello")
这就是一个Lambda表达式。它既是一个“参数”,更是一个“动作”。 第一次看的话,会觉得很奇怪,但是大概感受一下它的作用,便可以做出理解这整个动作:()表示实现的是一个无参的方法。->后面指向的一句话 System.out.pringln("hello");这句代码是方法体的具体实现,只是打印了一句话。这样理解就很顺了。下面再来看个例子。
使用Lambda表达式实现文件过滤
在File操作中我们可以实现 java.io.FileFilter 类来并在其accept 方法中编写过滤文件的代码实现。本例假设在windows系统中D盘有个文件夹resource,里边有一些文件,有.jc,.html,.doc 等各种格式。现在要选出js文件。实现如下:
例2-1
//1.文件目录 File fileDir=new File("D:/resource"); //2.创建筛选规则 FileFilter filter=new FileFilter() { @Override public boolean accept(File file) { if(!file.isDirectory()&&file.getName().endsWith(".js")){ return true; } return false; } }; //3.得到筛选文件 File[] files=fileDir.listFiles(filter);
其实功能很简单,但是代码不少。如果不是你写的,而是你在阅读别人的代码,恐怕不是一眼能看出来的。还得从上到下,把这几行都看了。但是,如果是lambda表达式写的话就会使下面这个样子:
例2-2
//1.文件目录 File fileDir=new File("D:/resource"); //2.筛选 File [] files=fileDir.listFiles((f)->!f.isDirectory()&&f.getName().endsWith(".js"));
怎么样,看起来是不是简洁多了。
(f)->!f.isDirectory()&&f.getName().endsWith(".js")
这一行就表到了上面4,5行的含义。因为括号中只有一个参数f,所以,也可以省去括号:
f->!f.isDirectory()&&f.getName().endsWith(".js")
写到这里。Lambda表达式的“长相”和“用途”已经展示出来了。个人感觉是优雅。只是初次看到的话,可能会觉得,一个括号,一个箭头。什么玩意。
但是当你理解了之后,看起来就会顺眼了。上面的两个例子,分别介绍了有参合无参,有返回值和无返回值的情况演示。基本够用了。具体编码用的时候,根据具体逻辑写实现就好了。例子中的lambda表达式是如下两种:
()-> xxx
(x,y)->x,y的处理
可以看到,结构为 三部分,箭头前的括号是方法头部分,箭头后面的是方法体实现。可以照葫芦画瓢,举一反三来写其他类型的lambda表达式写法。
1.如何理解lambda表达式。
答:其实就是一行代码,作为参数传递。既是一个参数,又是一组有“动作”的代码。
2.为什么例2-2中的代码,(f) 参数f参数类型都没有,一般的方法不都是指明参数类型的吗。这里都没说f是File类型的,为什么会不报错呢?
答:类型推断。
推荐阅读
[探索Java9 模块系统和反应流](https://www.cnblogs.com/demingblog/p/9104103.html)
Java8系列- 如何用Java8 Stream API找到心仪的女朋友
Java8系列- 何用Java8 Stream API进行数据抽取与收集
SpringMVC是怎么工作的,SpringMVC的工作原理
Mybatis Mapper接口是如何找到实现类的-源码分析