在Java基础课程中有一个工具非常好用,但不常用就很容易忘记。大家一定已经猜到,它就是Lambda表达式,一个会者不难的工具。今天我们就来快速熟悉下Lambda表达式。
1.没有Lambda表达式的编码习惯
先聊一个简单的面试题,匿名内部类和多态有什么关系?相信大家都会脑补在Java基础部分的内部类知识点。这个面试题的答案很简单,匿名内部类就是多态非常直观的体现。我们来看这个例子:
Runnable runnable = newRunnable() {
@Override
public void run() {
//线程体
System.out.println("lambda");
}
};
Runnable是线程类的上层接口。Runnbale接口的run方法是线程必须要重写的,也称为线程体。我们在使用Runnable来启动线程时就习惯使用上述这种写法,这也是多态的直观体现。但是有没有更简单的方式呢?Lambda表达式来秀一波。
Runnable runnable = () -> System.out.println("Lambda");
2.函数式接口
Lambda表达式实际上就是函数式接口的实现类的对象。因此要了解Lambda表达式,我们得先快速了解下什么是函数式接口。
@FunctionalInterface
public interface Runnable {
/**
* Runs this operation.
*/
void run();
}
这是Runnable接口的源码,Runnable接口就属于函数式接口。我们看到几个特点:
- 只有一个抽象方法的接口
- 使用@FuncationInterface注解来标识
3.Lambda表达式实现细节
知道了什么是函数式接口后,我们可以再来理解这句话:“Lambda表达式实际上就是函数式接口的实现类的对象”。此时我们就能明白,原来使用Lambda其实是在创建函数式接口的实现类的对象。
以第1小节为例,我们来看通过Lambda获得对象的演变过程:
- 先得到函数式唯一的抽象方法的参数列表,并用箭头符号(也称Lambda操作符)分割之后的内容。
Runnable runnable = ()-> {
//线程体
System.out.println("lambda");
}
};
箭头符号的左边"()"实际上就是"public void run()"方法的声明部分。这个括号描述的是run()方法的参数列表,而方法名、返回值类型、权限列表都被省略了。因为该接口只有一个抽象方法,这些内容可以自动被编译器识别。
- 简化箭头符号右边的内容:
如果只有一行代码,可以直接省略大括号。
Runnable runnable = () -> System.out.println("Lambda");
如果只有一行代码,且有return,则要么省略大括号和return,要么都不能省略。下面使用Lambda表达式创建compator接口对象为例。
//普通操作
Comparator<Integer> comparator1 = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;
}
};
//使用Lambda表达式创建
Comparator<Integer> comparator2 = (o1, o2) -> o1-o2;
从上述例子中可以快速看出,箭头符号的左边是方法的参数列表,箭头符号的右边是方法体由于只有一行代码,则把大括号和return都省略掉是没有问题的。
好了同学们,使用Lambda表达式简化代码就是这么简单。欢迎继续关注我们的技术分享。
标签:Runnable,run,接口,线程,熟悉,表达式,Lambda From: https://blog.51cto.com/u_15739596/9014837