Lambda表达式
函数式思想
在数学中,函数就是有输入量、输出量的一套计算方案,也就是“拿数据做操作”面向对象思想强调“必须通过对象的形式来做事情”函数式思想则尽量忽略面向对象的复杂语法:“强调做什么,而不是以什么形式去做”而我们要学习的Lambda表达式就是函数式思想的体现
ex01:体验lambda表达式
package LambdaDemo;
//需求:启动一个线程,在控制台输出一句话:多线程程序启动了
public class Demo01 implements Runnable {
@Override
public void run() {
System.out.println("线程启动了!");
}
}
public class Demo01Test {
public static void main(String[] args) {
Demo01 s1 = new Demo01();
Thread one = new Thread(s1);
one.start();
//方法二,匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程启动了!");
}
}).start();
//方法三Lambda表达式
new Thread( ()->{
System.out.println("多线程启动了!");
}).start();
}
}
Lambda表达式的标准格式
- (形式参数)->{代码块}
- 形式参数:如果有多个参数参数之间用逗号隔开;如果没有参数,留空即可
- ->:由英文划线与大于符号组成,固定写法。代表指向动作
- 代码块:是由我们具体要做的事情,也是以前我们写的方法体内容
Lambda表达式的使用前提
- 有一个接口
- 接口中有切仅有一个抽象方法
//接口
public interface Eatable {
void eat();
}
//实现类
public class Demo02Impll implements Eatable {
@Override
public void eat() {
System.out.println("少吃点,你太肥了");
}
}
//测试类
public static void main(String[] args) {
//主方法调用方法,调用方法,方法的参数为Etable e
Eatable S = new Demo02Impll();//采用多态的方法实例化对象
S.eat();
//匿名内部类
useEatable(new Eatable() {//调用方法,实现接口中的抽象方法,并重写方法达到内部类的作用
@Override
public void eat() {
System.out.println("不要再吃了");
}
});
//Lambda表达式
useEatable(()-> System.out.println("克制住,老铁"));
}
public static void useEatable(Eatable e){
e.eat();//调用接口中的方法
}
}
***当中的数据可以为一样的也可以为指定的只是为了体现不同的方法
接口中的抽象方法带参数
//接口
public interface Flyable {
void fly(String s);
}
public class Flayableimpl implements Flyable {
@Override
public void fly(String s) {
System.out.println("你要飞得更高");
}
}
//测试类
//定义一个接口(Flyable),里面定义一个抽象方法:void fly(String s);
//定义一个测试类(FlyableDemo),在测试类中提供两个方法
//一个方法是:useFlyable(Flyable f)
//一个方法是主方法,在主方法中调用useFlyable方法
public class Test {
public static void main(String[] args) {
Flyable fly = new Flayableimpl();
fly.fly("无语");
System.out.println("-----------");
//匿名内部类
useFlyable(new Flyable() {
@Override
public void fly(String s) {
System.out.println(s);
System.out.println("再小的帆也能远航!");
}
});
System.out.println("---------");
useFlyable((s)->{
System.out.println(s);
System.out.println("努力一点,拼命一点");
});
}
public static void useFlyable(Flyable f){
f.fly("风和日丽,晴空万里");
}
}
接口中的抽象方法带参数呆返回值
public interface Addable {
int add(int x,int y);//接口中只有一个方法
}
public class AddableDemo {
public static void main(String[] args) {
useAddable(new Addable() {//匿名内部类,与方法具体的执行有关
@Override
public int add(int x, int y) {
return x+y;
}
});
useAddable((int x,int y)->{//lambda表达式有一个接口 有且只有一个抽象方法
return x-y;
});
}
private static void useAddable(Addable a){
int sum = a.add(4, 6);
System.out.println(sum);
}
}
参数省略Lambda
//参数省略
public class test {
public static void main(String[] args) {
// useAdd((int x,int y)->{
// return x+y;
// });
// useAdd(( x, y)-> x+y);
// useFly((s)->{
// System.out.println(s);
// });
// }
//如果参数有且只有一个可以省略小括号,如果语句只有一条可以省略大括号与分号
useFly(s->
System.out.println(s)
);
}
private static void useFly(Fly f){
f.fly("飞呀飞");
}
private static void useAdd(addlist a){
int sum = a.add(10, 20);
System.out.println(sum);
}
}
public interface Fly {
void fly(String s);
}
public interface addlist {
int add(int x,int y);//需要两个int类型参数,返回一个int类型结果
}
Lambda表达式的注意事项
- 使用Lambda必须要有接口有且仅有一个方法
- 要有上下文环境
//接口
public interface enter {
void add();
}
//test
public class test {
public static void main(String[] args) {
addlist(()->System.out.println("超级大鸡腿"));//省略大括号与分号
new Thread(()-> System.out.println("蔡徐坤一点都不爷们")).start();//根据构造方法的参数得知lambda表达式接口是Runnable
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("你就是蔡徐坤嘛?");
}
}).start();
}
private static void addlist(enter e){
e.add();
}
}
Lambda表达式与匿名内部类的区别
public class LambdaDemo {
public static void main(String[] args) {
animal(new Animal() {
@Override
public void method() {
System.out.println("qaq");
}
});
inter(new Inter() {
@Override
public void init() {
System.out.println("ovo");
}
});
student(new Student(){
@Override
public void study(){
System.out.println("eve");
}
});
// animal(()-> System.out.println("123"));//抽象类不可以
// inter(()->System.out.println());//接口可以
// student(s-> System.out.println("学生"));//具体类不可以
}
private static void animal(Animal a){
a.method();
}
private static void inter(Inter i){
i.init();
}
private static void student(Student s){
s.study();
}
}
-
Lambda表达式不会产生字节码文件,匿名内部类会产生字节码文件。
-
使用限制不同接口中有且仅有一个抽象方法,可以使用两种方法。如果多于一种则不能使用Lambda表达式
-
所需的类型不同:匿名内部类可以是接口也可以是抽象类还可以是具体类,Lambda只能是接口
private static void student(Student s){
s.study();
}
}
[外链图片转存中...(img-W2MRUHi8-1617701585553)]
1. Lambda表达式不会产生字节码文件,匿名内部类会产生字节码文件。
2. 使用限制不同接口中有且仅有一个抽象方法,可以使用两种方法。如果多于一种则不能使用Lambda表达式
3. 所需的类型不同:匿名内部类可以是接口也可以是抽象类还可以是具体类,Lambda只能是接口