前言:
JDK8自2018年06月发布已经七年多了,由于国内开发环境有各种的老项目,有各种各样的发布风险,让公司以及项目组对新的技术往往望而却步。现在对jdk8新特性,很多同伴应该多多少少都知道,甚至已经在工作项目中使用。为了更多同伴能学习和掌握JDK8的新特性。我们接下来一起系统性的学习这块新特性。本章节重点讲解LAMBDA表达式的用法。
一、LAMBDA简介
jdk8新增了新语法lambdb表达式。lambda是一个匿名函数,在JDK8之前,Java是不支持函数式编程的。所谓的函数编程,即可理解是将一个函数(也称为“行为”)作为一个参数进行传递。通常我们提及得更多的是面向对象编程,面向对象编程是对数据的抽象(各种各样的POJO类),而函数式编程则是对行为的抽象(将行为作为一个参数进行传递)。使用lambda可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使JAVA的语言表达能力得到提升。
我们来看个示例比较下,创建一个线程并开始执行:
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("线程执行开始");
}
};
Thread thread = new Thread(runnable);
thread.start();
}
同样一个功能,我们再看下lambda的写法:
public static void main(String[] args) {
Runnable runnable = ()-> System.out.println("线程执行开始");
Thread thread = new Thread(runnable);
thread.start();
}
实现Runnable接口只用了一行代码。()-> System.out.println("线程执行开始")就是lambda表达式。我们看下这个表达的语法:
lamdba表达式新增了一个操作符->,称之为箭头操作符戓lambda操作符,箭头左侧为lambda表达式参数列表,右侧所需要功能代码,即lambda体。
二、LAMBDA使用场景
能够接收Lambda表达式的参数类型,是一个只包含一个run方法的接口。只包含一个方法的接口称之为“函数接口”,所以它可以使用Lambad表达式来代替匿名内部类。我们看下Runnable接口的源码:
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
在Runnable接口只定义 一个抽像方法,为了防止其他开发人员误加其他方法,在接口上加入注解@FunctionalInterface,如接口定义一个方法以上,则开发工具会有错误提示编译报错。函数接口后面我们会再详细讲解。
三、LAMBDA语法格式
了解了lambda使用场景,我们来看下对一个方法可以用不同的参数个数,以及用无返回值。对于这些方法情况,我们讲解下lambda语法格式:
1、无参、无返回值
对于无参,无返回值,如Runbable接口,这里()必须要用。如果lambda体中只有一行代码,可以不用写{},但如果是多行代码,必须写在{}里,这对其他情况的方法也一样。
()-> System.out.println("线程执行开始")
如下代码,线程休眠一秒再打印输出,此时代码须放入{}中。
Runnable runnable = ()-> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程执行开始");
};
2、无参、有返回值
我们写一个函数接口,无参且返回一个boolean型值
@FunctionalInterface
public interface LamdbaService {
boolean isAvailable();
}
来看下如何使用lambda表达式,这里是多行代码
public static void main(String[] args) {
LambdaService service = ()-> {
if(true){
return true;
}else {
return false;
}
};
}
如果是一行代码,则{}且不用return关键字定义可以省略
public static void main(String[] args) {
LambdaService service = ()-> true ? true: false;
}
3、有一个参数、有返回值
我们给上面接口方法重新定义下,传一个参数。
@FunctionalInterface
public interface LambdaService {
boolean isAvailable(String name);
}
我们看下代码的格式,传入一个参数,参数名自定义为t,参数类型可以省略,jvm可以通过推导方式判断参数类型
public static void main(String[] args) {
LambdaService service = (t) -> "admin".equals(t);
}
一个参数,大括号()可以省略输入:
public static void main(String[] args) {
LambdaService service = t -> "admin".equals(t);
}
4、有两个参数、有返回值
接口的方法重新定义,传入两个参数
@FunctionalInterface
public interface LambdaService {
boolean isAvailable(String name, Integer age);
}
再来看下lambda格式,两个参数,则()必须输入,不可省略
public static void main(String[] args) {
LambdaService service = (t, x) -> "admin".equals(t) && x > 20;
}
四、小结
本章节对于Lambda表达式只是到了一个“认识”的地步,似乎只是感受到了缩小代码量,对于Lambda式的认识不深入,更多的只是对于其他新特性做一个铺垫。Lambda表达式在并发编程、响应式编程等都有应用。
扫描下方二维码,关注微信公众号,掌握最新动态。与关注的同伴们一起学习,一起编程!