1. Lambda表达式
package Java31.Demo1;
public class demo {
public static void main(String[] args) {
//实现类的方式实现需求
// MyRunnable mr = new MyRunnable();
// Thread th1 = new Thread(mr);
// th1.start();
//匿名内部类方式改进
// new Thread(new Runnable() {
// @Override
// public void run() {
// System.out.println("多线程程序启动了");
// }
// }).start();
//Lambda表达式方式改进
new Thread(()->{
System.out.println("多线程程序启动了");
}).start();
}
}
package Java31.Demo1;
public class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("多线程程序启动了");
}
}
1.1 Lambda表达式的表准格式
Lambda表达式的表准格式:
- 格式:(形式参数) ->{代码块}
- 形式参数:如果有多个参数,用逗号隔开;如果没有参数,留空即可
- ->:代表指向动作
- 代码块:具体要做的事情,也就是要写的方法体内容
Lambda表达式的使用前提:
- 有一个接口
- 接口中有且只有一个抽象方法
接口Eatable
package Java31.Demo3;
public interface Eatable {
void eat();
}
接口实现类Eatableimpl
package Java31.Demo3;
//对接口进行方法冲写
public class Eatableimpl implements Eatable{
@Override
public void eat() {
System.out.println("ssssssssssssss");
}
}
测试类
package Java31.Demo3;
public class EatableDemo {
public static void main(String[] args) {
Eatable ea = new Eatableimpl();
ea.eat();
System.out.println("--------------");
//使用匿名内部类
useEatable(new Eatable() {
@Override
public void eat() {
System.out.println("ssssssssssssss");
}
});
System.out.println("----------------");
//使用Lambda表达式
useEatable(()->{
System.out.println("ssssssssssssssss");
});
}
private static void useEatable(Eatable e){
e.eat();
}
}
有参数接口的Lambda表达式使用
接口Flyable
package Java31.Demo4;
public interface Flyable {
void fly(String s);
}
测试类:
package Java31.Demo4;
public class FlyableDemo {
public static void main(String[] args) {
//使用匿名内部类方法
useFlyable(new Flyable() { //Flyable f = new Flyable();
@Override
public void fly(String s) {
System.out.println(s);
System.out.println("卷王");
}
});
//Lambda表达式的方法
useFlyable((String s)->{
System.out.println(s);
System.out.println("卷王");
});
}
private static void useFlyable(Flyable f){
f.fly("ssssssssssss");
}
}
多个参数下的Lambda表达式的案例
接口:
package Java31.Demo5;
public interface Addable {
int add(int x,int y);
}
测试:
package Java31.Demo5;
public class AddableDemo {
public static void main(String[] args){
//匿名内部类的方式
useAddable(new Addable() {
@Override
public int add(int x, int y) {
return x+y;
}
});
System.out.println("-------------");
//Lambda表达式
useAddable((int x,int y)->{
return x+y;
});
}
private static void useAddable(Addable a){
int sum = a.add(12,31);
System.out.println(sum);
}
}
1.2 Lambda表达式的省略模式
省略规格
- 参数类型可以省略,但是有多个参数的情况下,要么都省略要么都不省略
- 如果参数有且仅有一个,小括号可以省略
- 如果代码块的语句只有一条,可以省略大括号和分号,甚至是return
接口:
package Java31.Demo6;
public interface Addable {
int add(int x,int y);
}
package Java31.Demo6;
public interface Flyable {
void fly(String s);
}
测试:
package Java31.Demo6;
public class LambdaDemo {
public static void main(String[] args) {
uesAddable((int x,int y)->{
return x+y;
});
//参数的类型可以省略
uesAddable((x,y)->{
return x+y;
});
//但是有多个参数的情况下,不能只省略一个
// uesAddable((x,int y)->{
// return x+y;
// });
useFlyable((s)->{
System.out.println(s);
});
//如果参数有且仅有一个,那么小括号可以省略
useFlyable(s->{
System.out.println(s);
});
//如果代码块的语句只有一条可以省略大括号和分号
useFlyable(s-> System.out.println(s));
//如果有return,return也要省略(针对代码块只有一条语句
uesAddable((x, y) -> x+y);
}
private static void useFlyable(Flyable f){
f.fly("sssssssssssssssss");
}
private static void uesAddable(Addable a){
int sum = a.add(13,41);
System.out.println(sum);
}
}
1.3 Lambda表达式的注意事项
- 使用Lambda表达式必须要有接口,并且要求接口中有且仅有一个方法
- 必须有上下文环境,才能推导出Lambda对应的接口
根据局部变量的赋值得知Lambda对应的接口:Runnable r = ()-> System.out.println(“Lambda表达式”);
根据调用方法的参数得知Lambda表达式的接口:new Thread(()-> System.out.println(“Lambda表达式”)).start();
package Java31.Demo7;
/*
使用Lambda表达式必须有接口,且接口中仅有一个抽象方法
必须有上下文环境,才能推导出Lambda接口
* */
public class LambdaDemo {
public static void main(String[] args) {
//Lambda表达式
// useInter(()->{
// System.out.println("ssssssssssss");
// });
//省略简写
useInter(() -> System.out.println("ssssssssssssss"));
//必须有上下文环境,才能推导出Lambda接口
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类");
}
}).start();
// 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();
}
}
package Java31.Demo7;
public interface Inter {
void show();
// void method();
}
1.4 Lambda表达式和匿名内部类的区别
接口:
package Java31.Demo8;
public interface Inter {
void show();
}
package Java31.Demo8;
public interface Inter2 {
void show1();
void show2();
}
抽象类:
package Java31.Demo8;
public abstract class Animal {
public abstract void method();
}
具体类:
package Java31.Demo8;
public class Student {
public void study(){
System.out.println("卷王");
}
}
测试类:
package Java31.Demo8;
public class LambdaDemo {
public static void main(String[] args) {
//匿名内部类
useInter(new Inter() {
@Override
public void show() {
System.out.println("接口");
}
});
useAnimal(new Animal() {
@Override
public void method() {
System.out.println("抽象类");
}
});
useStudent(new Student(){
@Override
public void study() {
System.out.println("具体类");
}
});
//当接口中有两个抽象方法时只能使用匿名内部类
useInter2(new Inter2() {
@Override
public void show1() {
System.out.println("show1");
}
@Override
public void show2() {
System.out.println("show2");
}
});
System.out.println("-----------");
//Lambda表达式
useInter(()-> System.out.println("接口"));
// useAnimal(()-> System.out.println("抽象类"));//抽象类是无法使用Lambda表达式的
// useStudent(()-> System.out.println("具体类"));//具体类也不行
}
private static void useStudent(Student s){
s.study();
}
private static void useAnimal(Animal a){
a.method();
}
private static void useInter(Inter i){
i.show();
}
private static void useInter2(Inter2 i){
i.show1();
i.show2();
}
}
Lambda表达式和匿名内部类的区别
所需类型不同
- 匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
- Lambda表达式:只能是接口
使用限制不同
- 如果接口中仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
- 如果接口中有多个抽象方法,只能使用匿名内部类。
实现原理不同
- 匿名内部类:编译之后 ,产生一个单独的.class字节码文件
- Lambda表达式:编译之后,没有一个单独的字节码文件。对应的字节会在运行的时候动态生成。