Lanbda表达式的使用
练习2
- 定义一个接口flyable,里面定义一个抽象方法 void fly(String s)
- 定义一个测试类flyabledemo,在测试类中提供两个方法
一个方法是useFlyable(Flyable f)
主方法,在主方法中调用useflyable方法
package Demo16;
public interface Flyable {
void fly(String s );
}
package Demo16;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
public class FlyableDemo {
public static void main(String[] args) {
useFlyable(new Flyable() {
@Override
public void fly(String s) {
System.out.println(s);
System.out.println("飞机自驾游");
}
});
System.out.println("----------------");
useFlyable( (String s ) -> {
System.out.println(s);
System.out.println("飞机自驾游");
});
}
private static void useFlyable(Flyable f){
f.fly("风和日丽,晴空万里");
}
}
练习3
- 定义一个接口(Addable),里面定义一个抽象方法, int add(int x ,int y)
- 定义一个测试类(AddableDemo),在测试类中提供两个方法
一个方法是:useAddable(Addable)
一个主方法是,在主方法中调用useAddable方法
package Demo17;
public interface Addable {
int add(int x ,int y);
}
package Demo17;
public class AddableDemo {
public static void main(String[] args) {
//在主方法中调用useAddable方法
useAddable( (int x ,int y ) ->{
return x+y;//简化重写方法可以看做
});
}
private static void useAddable(Addable a){
int sum = a.add(10, 20);
System.out.println(sum);
}
}
Lambda表达式的省略模式
省略规则
- 参数类型可以省略,但是有多个参数的情况下,不能只省略一个
- 如果参数有且仅有一个,那么小括号可以省略
- 如果代码块的语句只有一条,可以省略大括号和分号,甚至是return。
package Demo17;
public class AddableDemo {
public static void main(String[] args) {
//在主方法中调用useAddable方法
// useAddable( (int x ,int y ) ->{
// return x+y;//简化重写方法可以看做
//参数的类型可以省略
// useAddable( (x,y) -> {
// return x+y;
// });
// //类型虽然可以省略,但是有多个参数的情况下不能只省略一个
// useFlyable( (String s ) -> {
// System.out.println(s);
// });//如果参数有且仅有一个,小括号可以省略
// useFlyable( s -> {
// System.out.println(s);
// });
//如果代码块的语句只有一条,可以省略大括号和分号
useFlyable( s -> System.out.println(s));
//useAddable( (x,y) -> return x+y);//如果有return,return也要省略,只针对代码块只有一条的情况
useAddable( (x,y) -> x+y);
}
private static void useAddable(Addable a){
int sum = a.add(10, 20);
System.out.println(sum);
}
private static void useFlyable(Flyable f){
f.fly("风和日丽,晴空万里");
}
}
Lambda使用注意事项
- 使用Lambda必须要有接口,并且接口中有且仅有一个抽此昂方法
- 必须有上下文环境,才能推导出lambda对应接口
根据局部变量的赋值得知lambda对应的接口:Runnable r = () -> System.out.println(“lambda表达式”);
根据调用方法的参数得知lambda对应的接口:new Thread( () -> System.out.println(“lambda表达式”)).start();
package Demo18;
public class LambdaDemo {
public static void main(String[] args) {
// useInter( () -> {
// System.out.println("好好学习,天天向上");
// });
//使用Lambda必须要有接口,并且接口有且仅有一个抽象方法
useInter( () -> System.out.println("好好学习,天天向上"));
//必须要有上下文华宁,才能推导出lambda对应接口
// new Thread(new Runnable() {
// @Override
// public void run() {
// System.out.println("匿名内部类");
// }
// });
Runnable r = () -> System.out.println("lambda表达式");
new Thread(r).start();
new Thread( () -> System.out.println("lambda表达式")).start();
}
private static void useInter(Inter i ){
i.show();
}
}
Lambda表达式和匿名内部类的区别
所需类型不同
- 匿名内部类:可以是接口,也可以是抽象类,还有可以是具体类
- lambda表达式:只能是接口
使用限制不同
- 如果接口中有且仅有一个抽象方法,可以使用lambda表达式,也可以使用匿名内部类
- 如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用lambda比表达式
实现原理不同
- 匿名内部类:编译之后,产生一个单独的.class字节码文件
- lambda表达式:编译之后,没有一个单独的.class文件,对应哪个的字节码会在运行的时候动态生成
package Demo19;
public class LambdaDemo {
public static void main(String[] args) {
匿名内部类,接口可以使用多个抽象方法
// useInter(new Inter() {
// @Override
// public void show1() {
// System.out.println("接口");
// }
// public void show2() {
// System.out.println("接口");
// }
// });
// useAnimal(new Animal() {
// @Override
// public void method() {
// System.out.println("抽象类");
// }
// });
// useStudent(new Student(){
// @Override
// public void study(){
// System.out.println("具体类");
// }
// });
//lambda,接口有且仅有一个抽象方法
// useInter( () -> System.out.println("接口"));
//useAnimal(() -> System.out.println("接口"));
// useStudent(() -> System.out.println("具体类"));
//使用lambda的地方参数必须是一个接口(有且只有一个)
}
private static void useStudent(Student s ){s.study();}
private static void useAnimal(Animal a ){a.method();}
private static void useInter(Inter i ){i.show1();i.show2();}
}