Lombda表达式是用简洁的代码创建只有一个抽象方法的接口(函数式接口),在这之前我们都是用匿名内部类创建的。
匿名内部类
先看例子
interface Dog{
void getColor();
void getName();
}
class RedDog implements Dog{
void getColor(){
System.out.pringln("我是Red");
}
void getName(){
System.out.pringln("我是Dog");
}
}
public class Test{
//用Dog作为参数
public void testDog(Dog d){
d.getColor();
}
public static void main(String [] args){
Test t=new Test();
RedDog dog=new RedDog();
t.testDog(dog);
}
}
通常我们要调用testDog方法时,我们就要传入Dog的实现类,于是我们实现了RedDog,但是我们有时候RedDog只用一次,而然还要创建RedDog不是很麻烦吗?于是可以用匿名内部类。
interface Dog{
void getColor();
void getName();
}
public class Test{
//用Dog作为参数
public void testDog(Dog d){
d.getColor();
}
public static void main(String [] args){
Test t=new Test();
t.testDog(new Dog(){
void getColor(){
System.out.pringln("我是Red");
}
void getName(){
System.out.pringln("我是Dog");
}
});
}
}
是不是感觉很熟悉,对的,我们经常再线程那边的run方法用到,对此我们可以得出,
匿名内部类主要用在只要用一次的时候,
其次他不能再次时抽象方法,要实现所有接口的方法,当然也可以实现接口的默认方法(JDK8) ,因为我们要创建对象,
然后他不能自定义构造方法,因为没有类名,所有只能用默认的构造方法
注意:在JDK8之前,我们在使用匿名内部类方法局部变量时,我们设置为final,但是JDK8后会自动给我们加上。
interface Dog{
void getName();
}
public class Test{
//用Dog作为参数
public void testDog(Dog d){
d.getColor();
}
public static void main(String [] args){
String name="redDog"
Test t=new Test();
t.testDog(new Dog(){
void getName(){
//在jdk8之前会报错,因为name没被final修饰
System.out.pringln(name);
}
});
}
}
Lombda表达式
Lombda表达式是用简洁的代码创建只有一个抽象方法的接口(函数式接口)实现类的对象,如:
匿名内部类
interface Dog{
void getName();
}
public class Test{
//用Dog作为参数
public void testDog(Dog d){
d.getColor();
}
public static void main(String [] args){
Test t=new Test();
t.testDog(new Dog(){
void getName(){
System.out.pringln("我是Dog");
}
});
}
}
Lombda表达式
interface Dog{
void getName();
}
public class Test{
//用Dog作为参数
public void testDog(Dog d){
d.getColor();
}
public static void main(String [] args){
Test t=new Test();
t.testDog(()->{
System.out.pringln("我是Dog");
}
});
}
}
从这段代码来看,使用Lombda来代替匿名匿名类创建对象时,将代替的是匿名内部类的方法体,所以Lombda只能代替一个方法体。于是我们可以得出lambda要的只有一个抽象方法的接口,不然实现不了其他方法,于是还是抽象类不能创建对象。
Lombda表达式的组成
() 这个是形参的部分,由于getName方法不用参数。就是一个括号就行
-> 必须要用英文的-和>组成
{} 这个是方法要实现的代码快
Lombda表达式几种简写的方式
1.当只有一个参数时,我们可以去掉()
interface Dog{
void getName(String name);
}
public class Test{
//用Dog作为参数
public void testDog(Dog d){
d.getColor();
}
public static void main(String [] args){
Test t=new Test();
String name="dog";
t.testDog(name->{
System.out.pringln("我是Dog");
}
});
}
}
2.当代码块只有一句时,可以去掉{}
interface Dog{
void getName(String name);
}
public class Test{
//用Dog作为参数
public void testDog(Dog d){
d.getColor();
}
public static void main(String [] args){
Test t=new Test();
String name="dog";
t.testDog(name->System.out.pringln("我是Dog");
});
}
}
3.当代码块只有一句时,改代码的值作为返回值,不用 return;
interface Dog{
String getName(String name);
}
public class Test{
//用Dog作为参数
public void testDog(Dog d){
d.getColor();
}
public static void main(String [] args){
Test t=new Test();
String name="dog";
t.testDog(name->"我是"+name;
});
}
}
函数式接口
上面说到只有一个抽象方法的接口是函数式接口,可以用Lombda表达式,那么JDK8中有很多都是这种的,如:Runable等等,其实可以分这几类:
XxxFunction:这种接口通常有个apply抽象方法,主要是用来对参数的处理转换,而然处理逻辑使用lambda表达式实现。最后返回值
XxxConsumer:这种接口通常有个accept抽象方法,主要用来对参数的处理转换,但是不返回值
XxxPredicate:这种接口通常包含一个test抽象方法,对参数的某种判断,返回boolean值,逻辑用lambda表达式实现
XxxSupplier:这种接口有个getAsXxx抽象方法,该方法不用参数,按照某种算法返回值
有了这些基础可以接着看这边文章深入了解lambda表达式JDK8特性一之Lambda表达式
原创来源:滴一盘技术