Java Lambda表达式

匿名内部类还有哪些缺点?

匿名内部类存在的一个问题是,如果匿名内部类的实现非常简单,例如只包含一个抽象方法的接口,那么匿名内部类的语法仍然显得比较冗余。

解决方法:

可以使用JDK 8中新增的Lambda表达式,这种表达式只针对有一个抽象方法的接口实现,以简洁的表达式形式实现接口功能来作为方法参数。
举例:

public Interface Animal//动物接口
{
void eat();//抽象方法
}
public class Dog implements Animal//狗类实现动物接口
   {//
public void eat()//重写方法
{
System.out.println("狗吃骨头");
 }

  }//
  
public class Master{
public void feed(Animal a)//传一个接口
{
a.eat();
}

}
public class Test//测试类
{
public static void main(String []args)
{
Master m=new Master();
/*m.feed(new Animal(){//本来应该传new Dog(),但这里运用匿名内部类new 父类名字或者接口的名字,所以按照这样写,需要实现接口中的方法.
public void eat()
{
System.out.println("狗吃骨头");
}
});*/
m.feed(()->{
System.out.println("狗吃骨头");
});

}

}


注意:
接口中有且只有一个抽象方法时才能使用Lamdba表达式代替匿名内部类.

这是因为Lamdba表达式是基于函数式接口实现的,所谓函数式接口是指有且仅有一个抽象方法的接口 Lambda表达式就是Java中函数式编程的体现,只有确保接口中有且仅有一个抽象方法,Lambda表达式才能顺利地推导出所实现的这个接口中的方法。
JDK8之后,接口中可以有default 修饰的默认的方法体,以及static修饰的方法体,它们不算抽象方法,只要接口中有且仅有一个抽象方法即函数式接口


@FunctionalInterface//编译器会帮忙检测下面是否为一个函数式接口
public interface A{
 }
 
interface B{
void show ();
 }
 
interface C{
void show ();
void m();

 }
 
interface D{
void show ();
static void m(){};

 }
 
interface E{
void show ();
default void m(){};

 }

Lanmbda表达式

 ([数据类型 参数名,数据类型 参数名,...]) -> {表达式主体}

①用来向表达式主体内部实现的接口方法传入参数。多个参数之间用逗号分隔,可以省略数据类型,只有一个参数时还可以省略小括号
②表示Lambda表达式箭牌,用来指定参数数据指向,不能省略
本质就是接口中抽象方法的具体实现。如果只有一条语句,可以省略大括号;在Lambda表达式主体中只有一条return语句时,也可以省略return关键字

public interface NoparNoreturn{//接口
void m1();
}
 interface SinglparNoreturn{
 void m2(int a);
}
 interface MultiparNoreturn{
 void m3(int a,int b);
}
interface NoparYesreturn{
int m4();
}
 interface SinglparNoreturn{
 void m5(int a);
}
interface MultiparNoreturn{
void m6(int a,int b);
}


public class Demo{//测试类
public static void main(String[] args)
{
NoarNoreturn nn=()->{
System.out.println("hello");//匿名重写方法
};
nn.m1();//第一种形式,调用和抽象方法一样的方法名.


yanzheng(()->{//第二种形式
System.out.println("hello");
});


SinglparNoreturn sn=(int a)->{
System.out.println(a);//用Lanmbda表达式实现了接口中方法的重写
};
sn.m2(36);//第三种形式,有参数的



SinglparNoreturn sn1=new QQ();
sn1.m2(66);//这是复杂版的,利用Lanmbda表达式其实就是简化了实现类

MultiparNoreturn mn=()->{
System.out.println(a+b);
};
mn.m3(34,12);



yanzheng1((int a)->System.out.println(a),88);//匿名实现抽象类方法并且简化


NoparYesreturn ny=()->100;//只有一条语句并且是返回值时,可以写成这样.
NoparYesreturn ny=()->{//这是重写的方法体
System.out.println("abc");
return 100;
}
System.out.println(ny.m4());//调用重写的方法体


NoparYesreturn sy=a->a;//只有一个参数时,有一个返回值,可以省略小括号和大括号.
System.out.println(sy.m5(90));


MultiparNoreturn my=(a,b)->a+b;
System.out.println(m6.(12,67));

}


public static void yanzheng(NoparNoreturn nn)//第二种形式的方法
{
nn.m1();
}
public static void yanzheng1(NoparNoreturn nn,int a){
nn.m2(a);
}
}


public class QQ implements SinglparNoreturn{
public void m2(int a){//重写接口的方法
System.out.println(a);
}
}

Lanmbda方法体只有一句表达式时,可以省略大括号

方法引用与构造器的引用

interface MultiparNoreturn{
void m6(int a,int b);
}

public class Demo{
public static void main(String[] args)
{

//Lanmbda表达形式
MultiparNoreturn my=(a,b)->fab(a,b);

//方法引用形式
MultiparNoreturn my1=Demo::fab;//前提是此类的静态方法
System.out.println(my.m6(12,6));
}
public static int fab(int a,int b){
return a*b;
}
}


方法引用求绝对值

public class Math{
public static int abs(int num){
if(num<0)
return -num;
else 
return num;
}
}

public interface Calcable{
int cal(int num);
}

public class CalTest{
public static void main(String []args)
{//此为Lanmbda表达形式,但如果有一个类已经实现了
Calcable c=num->{
if(num<0)
return -num;
else 
return num;
};
Calcable c=Math::abs;//方法引用的形式
System.out.println(c.cal(-34));
printAbs(-34,num->Math.abs(num));
printAbs(-34,Math::abs);//方法引用

}
public static void printAbs(int num,Calcable c){//如果接口里面有参数,括号里面就有什么参数,另外加一个接口参数
System.out.println(c.cal(num));
}
}

构造器的引用

public class Person{
String name;
int age;
public Person(){
System.out.println("无参构造方法执行了");
}
public Person(String name,int age)
{
this.name=name;
this.age=age;
System.out.println("有参构造方法执行了");
System.out.println(name+" "+age);
}
}


public interface PersonInter{
Person getPerson();//一定要返回一个类的对象
}
interface PersonInter1{
Person getPerson(String name,int age);
}


public class PersonTest{
public static void main(Stirng [] args)
{

PersonInter pi=()->new Person();//Lanmbda表达形式创建一个无参的Person对象
pi.getPerson();

PersonInter1 pi2=Person::new ;
pi2.getPerson("zhangsan",23);

}

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值