Lambda表达式
为什么要使用lambda表达式
- 避免匿名内部类定义过多
- 可以让代码看起来更简洁
- 去掉了没有意义的代码,只留下核心的逻辑。
理解Functional Interface(函数式接口)是学习Java8 lambda表达式关键所在。
函数式接口是Lambda表达式的前提。
什么是Functional Interface(函数式接口)
-
任何接口,如果只包含唯一一个抽象方法,那么它就是一个函数式接口。如下:
//只包含一个抽象方法的接口,如下就是一个函数式接口 public interface Runnable{ public abstract void run(); }
JDK中也提供了许多函数式接口,比如我们熟悉的 Runnable 接口和 Callable 接口:
如图所示: 两段源码中均对接口加上了一个注解:@FunctionalInterface ,顾名思义,这表示该接口会被设计成一个函数式接口,不符合规范的话,编译时会报错。
-
对于函数式接口,可以通过lambda表达式来创建该接口的对象
-
故函数式接口是Lambda表达式实现的前提。
Lambda表达式的由来(推导)
普通接口实现类形式
//普通接口实现类的形式
public class Demo01 {
public static void main(String[] args) {
ILike iLike = new Like();
iLike.like();
}
}
interface ILike{
void like();
}
//普通实现类
class Like implements ILike{
@Override
public void like() {
System.out.println("I'm Carson!(普通实现类)");
}
}
缺点:
ILike这个接口仅仅是在Demo01这个类中使用,所以是没必要新建一个外部Like实现类的。
实现类作为静态内部类形式
//实现类作为静态内部类形式
public class Demo02 {
//静态内部类
static class Like implements ILike{
@Override
public void like() {
System.out.println("I’m Carson!(静态内部类)");
}
}
public static void main(String[] args) {
//内部类可以无条件访问外部类的属性和方法
//外部类访问内部类的属性和方法,必须创建内部类对象,才能访问
ILike iLike = new Like();
iLike.like();
}
}
}
interface ILike{
void like();
}
缺陷:
代码仍存在冗余,不够简洁。
实现类作为局部内部类形式
//实现类作为局部内部类形式
public class Demo03 {
public static void main(String[] args) {
//内部类可以无条件访问外部类的属性和方法
//外部类访问内部类的属性和方法,必须创建内部类对象,才能访问
ILike iLike = new Like();
iLike.like();
//局部内部类(在方法内部的内部类)
class Like implements ILike{
@Override
public void like() {
System.out.println("I'm Carson!(局部内部类)");
}
}
}
}
interface ILike{
void like();
}
缺陷:
代码仍存在冗余,不够简洁。
实现类作为匿名内部类形式
//接口实现类作为匿名内部类形式
public class Demo04 {
public static void main(String[] args) {
ILike iLike = new ILike() {
@Override
public void like() {
System.out.println("I'm Carson!(匿名内部类)");
}
//注意匿名内部类要求
}; //此处要有一个分号结尾
//调用方法
iLike.like();
}
}
//定义一个函数式接口
interface ILike{
void like();
}
Lambda表达式的引入
上面的匿名内部类的核心代码如下:
//格式:接口名 引用变量名 = new 接口名(){重写方法内容};
ILike iLike = new ILike() {
@Override
public void like() {
System.out.println("I'm Carson!(匿名内部类)");
}
};
匿名内部类的好处是省略了类名。但因为ILike是一个函数式接口,只有一个固定的一个抽象方法,故还可以继续省略接口名,方法名等信息,由于只有一条语句,还可以省略花括号{}。
即接近lambda表达式的形式,如下:
ILike iLike = () System.out.println ( "I'm Carson!" ) ;
再转变为真正的Lambda的形式如下:需要添加一个"->"符号:
ILike iLike = ()->System.out.println ( "I'm Carson!" ) ;
所以Lambda表达式可以将一个复杂的代码块缩短成了最简单的一行代码,这种用“->”符号来编写的表达式,便叫做Lambda表达式。
//Lambda表达式的常见格式:
()->{}; //注意结尾的冒号
从上述过程也可以看出,Lambda表达式的优点在于能够使代码变得更为简洁。
化简成Lambda表达式的常用规则
1.//如果接口实现类的语句不止一句,则必须加上花括号{},如下:
ILike iLike = ()->{
System.out.println("I’m Carson!");
System.out.println("I'm 小Carson!");
};
//否则可以省略花括号{},如下:
ILike iLike = ()->System.out.println ( "I'm Carson!" ) ;
//定义一个函数式接口
interface ILike{
void like(int a);
}
2.//如果接口的抽象方法有且仅含有一个参数(比如是int a,这时可以省略括号和变量类型:int)
ILike iLike = a -> System.out.println("I'm Carson!");
//定义一个函数式接口
interface ILike{
void like(int a,String b);
}
3.//如果接口含有多个参数(比如含有int a,String b),这时不能省略括号,但仍可以省略变量类型:int和String),变成如下的形式:
ILike iLike = (a,b) -> System.out.println("I'm Carson!");
The End!!创作不易,欢迎点赞/评论!!欢迎关注个人公众号