什么是Lambda表达式?
在java的学习过程中,你是否见过如下图这样的代码:
初看时你可能不求甚解,但如果你有一定的java基础,你应该可以看出这段代码做了什么。首先,这段代码声明了一个接口对象,然后这个对象调用了一个print()方法,然后打印出了一段信息。
那么问题来了,我们都知道,接口不能实例化,它必须接收一个实现类的对象,才可以去调用被实现类重写的方法,否则就会编译报错,但是,本来属于new一个实现类的地方,现在却被一段奇怪的代码代替了:
而这段奇怪的代码就是我们今天所要谈到的lambda表达式。
为什么要使用lambda表达式?
在程序开发中,有些时候,我们可能想传递一些简单的代码块,但在javaSE8以前,这样的想法是行不通的,
即使只要简单的两三行语句,如果想传递给程序的其它地方,例如另一个类中,我们也必须为这个代码块定
义一个类,然后把这个代码块封装成类中的一个方法,最后通过传递这个类的对象,间接实现这个代码块的
传递,而这样无疑是十分繁琐的,而在javaSE8中,这个问题终于得到了解决,即—lambda表达式
lambda表达式是什么?
在回答这个问题之前,我们先谈谈lambda表达式是如何解决上述我们提出的问题的,实际上,lambda表达式在调用时底层会返回返回一个类的对象。例如开篇我们提到的那个关于接口的例子,我们可以看到interface1的右边就是一个lambd表达式,而这个lambda表达式就会返回一个interface1实现类的对象,这个对象完成了对print()方法的重写,当interface1调用print()方法时,实际上就是在调用lambda表达式中的内容,这也解答了我们开篇提出的问题,这也折射初lambda表达式与接口的紧密联系,实际上,在java中,lambda表达式的主要用途就是对接口的实现。
lambda表达式的语法:
(参数一、参数二…)—>{ 要书写的语句};
以上是lambda表达式的常见形式,但在几种特殊情况下,它还有几种变体:
- 当参数只有一个时,括号可以省略:
int x一 —>{要书写的语句};
- 当要书写的语句只有一条时,花括号可以省略,例如
int x —> x++;
如果一个 lambda 表达式只在某些分支返回一个值, 而在另外一些分支不返回值, 这是不合法的。例如,(int x)-> { if(x >= 0) return 1; } 就不合法。
方法引用(细节请读者自行查阅资料,这里就不展开叙述了)
object::instanceMethod
Class**😗*:staticMethod
Class::instanceMethod
lambda表达式与接口实现:
前面说过,lambda表达式在java中的主要用途就是用来实现接口,而这要遵循以下几个准则
- 被重写的接口只能有一个抽象方法(考虑到javaSE8以后接口也可以有默认方法,故特此说明,javaSE8以前这条准则就变为接口中只能有一个方法)
- lambda表达式的参数类型,顺序,个数必须和接口中的抽象方法保持一致
- 抽象方法若不为void,则lambda表达式必须提供返回值(返回值可以被推测出则不用,例如comparator的应用)
- 即使 lambda 表达式没有参数, 仍然要提供空括号,就像无参数方法一样
一些简单的例子: