JAVA Lambda表达式
Lambda表达式
冗余的Runnable代码
函数式编程
面对对象的思想
做一件事情,找一个能解决这个事情的对象,调用对象的方法,完成这个事情
函数式编程的思想
只要获取到结果,谁去做的,怎么做的都不重要,重视结果不重视过程。
代码实现
package project;
/*
* 使用Runnable接口的方式实现多线程程序
*/
public class test{
public static void main(String[] args) {
//创建Runnable接口的实现类对象
test01 t1=new test01();
//创建thread对象 构造方法中传递Runnable接口的实现类
Thread t=new Thread(t1);
//调用start方法开启新线程 执行run方法
t.start();
//简化代码 使用匿名内部类 实现多线程程序
Runnable r=new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"新的线程创建了");
}
};
new Thread(r).start();
//再简化代码
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"新的线程创建了");
}
}).start();
}
}
test01类:
package project;
/*
*创建Runnable接口的实现类 重写run方法,设置线程任务
*/
public class test01 implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"新的线程创建了");
}
}
代码分析
对于Runnable
的匿名内部类用法 可以分析出
Thread
类需要Runnable
接口作为参数,其中的抽象方法run
是用来指定线程任务内容的核心- 为了指定
run
的方法体 不得不需要Runnable
接口的实现类 - 为了省区定义一个
Runnable
实现类的麻烦 不得不使用匿名内部类 - 必须覆盖重写抽象
run
方法 所以方法名称 方法参数 方法返回值不得不再写一遍 并且不能写错 - 实际上 似乎只有方法体才是关键所在
编程思想的转换
做什么,而不是怎么做
我们不是真的想创建一个匿名内部类对象,我们只是为了做这件事情而不得不创建一个对象。我们真正希望做的事情是:将run
方法体内的代码传递给Thread
类知道
传递一段代码 这才是我们真正的目的 而创建对象只是限于面对对象语法而不得不采用的一种手段
如果将怎么做回归到做什么的本质上 就会发现只要能够更好的达到目的 过程和形式并不重要
Lambda的更优写法
代码
使用Lambda表达式实现上述Runnable匿名内部类的效果
package project;
/*
* 使用Lambda表达式来实现优化
*/
public class test{
public static void main(String[] args) {
new Thread(()->System.out.println("多线程任务执行")).start();//启动线程
}
}
。。。确实有点简单哦
语义分析
Runnable
接口只有一个run
方法的定义:
public void run();
即制定了一种做事情的方案(一个函数):- 无参数:不需要任何条件就可以执行该方案
- 无返回值:该方案不产生任何结果
- 代码块(方法体):该方案的具体执行步骤
同样的予以体现在Lambda
语法中 要更加简单
()->System.out.println("多线程任务执行")
- 前面的一对小括号就是
run
方法的参数(无) 代表不需要任何田间 - 中间的一个箭头代表将前面的参数传递给后面的代码
- 后面的输出语句就是业务逻辑代码
标准格式
- 一些参数
- 一个箭头
- 一段代码
Lambda标准格式为
(参数类型 参数名称)->{ 代码语句 }
格式说明:
- 小括号内的语法与传统方法参数列表一致:无参数留空; 多个参数则用逗号分隔
->
是新引入的语法形式, 代表指向动作- 大括号内的语法与传统方法体要求基本一致(需要执行的代码)
无参数无返回值代码练习
Cook接口:
package project;
public interface Cook {
void makeFood();
}
main:
package project;
/*
* Lambda标准格式
* 由三部分组成
* a 一些参数
* b 一个箭头
* c 一段代码
* 格式:
* (参数类型 参数名称)->{ 代码语句 }
* 解释说明格式:
* 小括号内的语法与传统方法参数列表一致:无参数留空; 多个参数则用逗号分隔
* ```->```是新引入的语法形式, 代表指向动作
* 大括号内的语法与传统方法体要求基本一致(需要执行的代码)
*
* 需求:
* 给定一个Cook厨子接口 内含唯一的抽象方法makeFood 且无参数 无返回值
* 使用Lambda表达式调用invokeCook方法 打印输出“吃饭了!”字样
*/
public class test{
public static void main(String[] args) {
//使用Lambda表达式调用invokeCook方法
//匿名内部类
invokeCook(new Cook() {
@Override
public void makeFood() {
System.out.println("吃饭了!");
}
});
//使用Lambda表达式
invokeCook(()->
{
System.out.println("吃饭了!");
}
);
}
//定义了一个方法 参数传递了Cook接口 方法内部调用Cook接口中的方法makeFood
private static void invokeCook(Cook cook) {
cook.makeFood();
}
}
有参数有返回值代码练习
Person类:
package project;
public class Person {
private String name;
private int age;
public Person() {
// TODO Auto-generated constructor stub
}
public Person(String name,int age){
this.age = age;
this.name = name;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "Person{"+
"name='"+name+'\''+
",age="+age+
'}';
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
}
匿名内部类和Lambda表达式的对比
package project;
/*
* Lambda表达式有参数有返回值的练习
* 需求:
* 使用数组存储多个Person对象
* 对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序
*/
import java.util.Arrays;
import java.util.Comparator;
public class test{
public static void main(String[] args) {
//使用数组存储多个Person对象
Person[] arr= {
new Person("刘艳",18),
new Person("张三",25),
new Person("赵四",20),
};
//对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序
// Arrays.sort(arr,new Comparator<Person>() {
//
// @Override
// public int compare(Person o1, Person o2) {
//
// return o1.getAge()-o2.getAge();
// }
// });
//使用Lambda表达式 简化匿名内部类
Arrays.sort(arr,(Person o1,Person o2)->{
return o1.getAge()-o2.getAge();
});
//遍历数组
for(Person p:arr) {
System.out.println(p);
}
}
}
Lambda省略
省略规则
在Lambda标准格式的基础上,使用省略写法的规则为:
- 小括号内参数的类型可以省略;
- 如果小括号内有且仅有一个参,则小括号可以省略;
- 如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号。
省略练习
非省略形式
Arrays.sort(arr,(Person o1,Person o2)->{
return o1.getAge()-o2.getAge();
});
省略形式
Arrays.sort(arr,(o1,o2)->o1.getAge()-o2.getAge());