Lambda表达式
产生条件
创建一个新的线程,并执行相关任务
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程中的方法执行..."+Thread.currentThread().getName());
}
}).start();
System.out.println("主线程执行..."+Thread.currentThread().getName());
}
代码分析:
- Thread类需要一个Runnable接口作为参数,其中的抽象方法run方法是用来指定线程任务内容的核心
- 为了指定run方法体,不得不需要Runnable的实现类
- 为了省去定义一个Runnable 的实现类,不得不使用匿名内部类
- 必须覆盖重写抽象的run方法,所有的方法名称,方法参数,方法返回值不得不都重写一遍,而且不能出错
- 而实际上,我们只在乎方法体中的代码
为了简化代码Lambda表达式就产生了,上面的代码用Lambda表达式写法为:
public static void main(String[] args) {
new Thread(()-> {
System.out.println("线程方法执行..."+Thread.currentThread().getName());
}).start();
System.out.println("主线程执行..."+Thread.currentThread().getName());
}
代码分析:
- 简化了匿名内部类的使用,语法更加简单
- Lambda表达式是简化匿名内部类的一种方式
Lambda的语法规则
(参数类型 参数名称) - > { 逻辑代码; }
格式说明:
- (参数类型 参数名称) :参数列表
- -> : 箭头,分割参数列表和方法体
- { 逻辑代码; }:方法体
- lambda略写法的规则为:
- 小括号内的参数类型可以省略
- 如果小括号内有且仅有一个参数,则小括号可以省略
- 如果大括号内有且仅有一个语句,可以同时省略大括号,return 关键字及语句分号
Lambda练习
1、无返回值的Lambda
1、准备一个接口
public interface UserService {
void addUser();
}
2 and 3、使用
public static void main(String[] args) {
addUsers(()-> System.out.println("Lambda方法执行..."));
}
private static void addUsers(UserService userService){
userService.addUser();
}
2、有参数有返回值的Lambda
1、创建一个实体对象
public class User {
private int id;
private String userName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public User(int id, String userName) {
this.id = id;
this.userName = userName;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", userName='" + userName + '\'' +
'}';
}
}
2、用原来的方法进行List排序
public static void main(String[] args) {
//list里面封装3个user
List<User> users=new ArrayList<>();
users.add(new User(1,"张三"));
users.add(new User(5,"李四"));
users.add(new User(2,"王五"));
//用原来得方式进行排序
Collections.sort(users, new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o1.getId()-o2.getId();
}
});
//验证
for (User user : users) {
System.out.println(user);
}
}
3、用Lambda的方法进行List排序
public static void main(String[] args) {
//list里面封装3个user
List<User> users=new ArrayList<>();
users.add(new User(1,"张三"));
users.add(new User(5,"李四"));
users.add(new User(2,"王五"));
//用lambda进行排序
Collections.sort(users,(User u1,User u2) -> {
return u1.getId()-u2.getId();
});
//验证
for (User user : users) {
System.out.println(user);
}
}
@FunctionalInterface注解
这是一个标志注解,被该注解修饰的接口只能声明一个抽象方法
效果:
Lambda表达式的省略写法
在lambda表达式的标准写法基础上,可以使用省略写法的规则为:
- 小括号内的参数类型可以省略
- 如果小括号内有且仅有一个参数,则小括号可以省略
- 如果大括号内有且仅有一个语句,可以同时省略大括号,return 关键字及语句分号。
Lambda表达式的使用前提
Lambda表达式的语法是非常简洁的,但是Lambda表达式不是随便使用的,使用时有几个条件要特别注
意 1. 方法的参数或局部变量类型必须为接口才能使用Lambda
2. 接口中有且仅有一个抽象方法(@FunctionalInterface)
Lambda和匿名内部类的对比
Lambda和匿名内部类的对比
- 所需类型不一样
- 匿名内部类的类型可以是 类,抽象类,
- 接口 Lambda表达式需要的类型必须是接口
- 抽象方法的数量不一样
- 匿名内部类所需的接口中的抽象方法的数量是随意的
- Lambda表达式所需的接口中只能有一个抽象方法
- 实现原理不一样
- 匿名内部类是在编译后形成一个class
- Lambda表达式是在程序运行的时候动态生成class