lambda表达式学习笔记
文章目录
1 lambda语法
Printer.java
package com.tangguanlin.lambda;
public interface Printer {
void printer(String val);
}
LambdaDemo.java
package com.tangguanlin.lambda;
/**
* 作者:汤观林
* 完成日期:2021年05月04日
*/
public class LambdaDemo {
public void printSomething(String something, Printer printer){
printer.printer(something);
}
}
LambdaDemoTest.java
package com.tangguanlin.lambda;
/**
* 不用lamdba表达式的实现
* 作者:汤观林
* 完成日期:2021年05月04日
*/
public class LambdaDemoTest {
public static void main(String[] args) {
LambdaDemo lambdaDemo = new LambdaDemo();
String something ="tewssss";
//传统方式实现接口
Printer printer = new Printer() {
@Override
public void printer(String val) {
System.out.println(val);
}
};
//用lamdba表达式实现接口 简化0
Printer printer0 = (String val)->{
System.out.println(val);
};
//用lamdba表达式实现接口 简化1
Printer printer1 = (val)->{
System.out.println(val);
};
//用lamdba表达式实现接口 简化2
Printer printer2 = (val)->System.out.println(val);
//用lamdba表达式实现接口 简化3
Printer printer3 = val->System.out.println(val);
//用lamdba表达式实现接口 简化4
lambdaDemo.printSomething(something,val->System.out.println(val));
lambdaDemo.printSomething(something,printer1);
}
}
2 list转map list过滤
Person.java
package com.tangguanlin.lambda;
/**
* 作者:汤观林
* 完成日期:2021年05月04日
*/
public class Person {
private String name;
private int age;
public Person() {
}
public String getName() {
return name;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
ListToMap.java
package com.tangguanlin.lambda;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* list转map list过滤
* 作者:汤观林
* 完成日期:2021年05月04日
*/
public class ListToMap {
public static void main(String[] args) {
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("zhangsan",11));
personList.add(new Person("lisi",12));
personList.add(new Person("wangwu",13));
personList.add(new Person("zhaoliu",15));
personList.add(new Person("lidamazi",15));
//list转map age:name
Map<Integer,String> personMap = personList.stream().collect(Collectors.toMap(Person::getAge,Person::getName,(k1,k2)->k2));
//list转map age:person
Map<Integer,Person> personMap2 = personList.stream().collect(Collectors.toMap(Person::getAge, Function.identity(),(k1, k2)->k2));
//对list进行过滤
List<Person> selectedList = personList.stream().filter((Person person)->person.getAge()<15).collect(Collectors.toList());
//对list进行过滤后再转map
Map<Integer,Person> personMap3 = personList.stream().filter((Person person)->person.getAge()<15).collect(Collectors.toMap(Person::getAge, Function.identity(),(k1, k2)->k2));
}
}
3 stream流
Employee.java
package com.tangguanlin.lambda;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* 作者:汤观林
* 完成日期:2021年05月04日
*/
@AllArgsConstructor
@Data
public class Employee {
private int id;
private int age;
private String gender;
private String firstName;
private String lastName;
}
StreamFilterPredicate.java
package com.tangguanlin.lambda;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* stream流
* 作者:汤观林
* 完成日期:2021年05月04日
*/
public class StreamFilterPredicate {
public static void main(String[] args) {
List<String> playerList = Arrays.asList("kobe","james","curry","cyyt");
//数组,Set,文件都可以转为管道流
List<String> playerSortedList = playerList.stream() //list转为管道流
.filter(s->s.startsWith("c")) //过滤
.map(String::toUpperCase) //变成大写
.sorted() //排序
.collect(Collectors.toList()); //流转为list
//最后结果能转为List,Map,Set
System.out.println(playerSortedList);
Employee e1 = new Employee(1,23,"M","Rick","Beethovan");
Employee e2 = new Employee(2,13,"M","Rick","Hengis");
Employee e3 = new Employee(3,43,"M","Ricky","Martin");
Employee e4 = new Employee(4,26,"M","Jon","Lowman");
Employee e5 = new Employee(5,49,"F","Cristine","Maria");
Employee e6 = new Employee(6,15,"M","David","eezor");
Employee e7 = new Employee(7,68,"F","Melissa","Roy");
Employee e8 = new Employee(8,79,"M","Alex","Gussin");
Employee e9 = new Employee(9,15,"F","Neetu","Singh");
Employee e10 = new Employee(10,45,"M","Nayeen","Jain");
List<Employee> employees = Arrays.asList(e1,e2,e3,e4,e5,e6,e7,e8,e9,e10);
//数组,Set,文件都可以转为管道流
//1.filter用法
List<Employee> employees1 = employees.stream()
.filter(e->e.getAge()>70&&e.getGender().equals("M"))
.collect(Collectors.toList());
//最后结果能转为List,Map,Set
//2.map的用法:对每个元素进行处理
List<Employee> employees2=employees.stream()
.map(e->{
e.setAge(e.getAge()+1);
e.setGender(e.getGender().equals("M")?"male":"female");
return e;
})
.collect(Collectors.toList());
//3.map+forEach 的用法:对每个元素进行处理 输出每个元素
employees.stream()
.map(e->{
e.setAge(e.getAge()+1);
e.setGender(e.getGender().equals("M")?"male":"female");
return e;
})
.forEach(e->System.out.println(e.getFirstName()));
//4.limit 去前几个
List<Employee> employees3=employees.stream()
.limit(2) //取前2个
.collect(Collectors.toList());
//5.skip 跳过前几个
List<Employee> employees4=employees.stream()
.skip(2) //跳过前2个
.collect(Collectors.toList());
//6.distinct 去重
List<Employee> employees5 =employees.stream()
.distinct()
.collect(Collectors.toList());
//7.sorted 排序
List<Employee> employees6 = employees.stream()
.sorted(Comparator.comparing(Employee::getAge))
.collect(Collectors.toList());
//8.sort 排序 按年龄倒序排序
employees.sort(Comparator.comparing(Employee::getGender) //性别倒序
.thenComparingInt(Employee::getAge) //年龄倒序
.reversed() //倒序
);
//9.anyMatch 是否存在(有1个就算)
boolean isHave = employees.stream().anyMatch(e->e.getAge()>10);
//10.allMatch 是否所有的人年龄都大于18
boolean isHave2 = employees.stream().allMatch(e->e.getAge()>18);
//11.noneMatch 没有1个 小于18岁的
boolean isHave3 = employees.stream().noneMatch(e->e.getAge()<18);
//12.查找 元素
Optional<Employee> OptionalEmployee = employees.stream()
.filter(e->e.getAge()>10)
.findFirst();
Employee employee7 = OptionalEmployee.get();
}
}
4 lambda应用场景
Lambda 表达式是 Java 8 引入的新特性,结合 forEach 方法可以更方便地实现遍历。
此外,它还可代替 Runnable 类,大大简化了代码的编写。
下面介绍了一些常见的应用场景,在这些场景中适时地使用 Lambda 表达式要比通常的方式来得更加简洁和方便。
4.1 列表迭代
对一个列表的每一个元素进行操作,不使用 Lambda 表达式时如下:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
for (int element : numbers) {
System.out.prinln(element);
}
使用 Lambda 表达式:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.forEach(x -> System.out.println(x));
如果只需要调用单个函数对列表元素进行处理,
那么可以使用更加简洁的 方法引用 代替 Lambda 表达式:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.forEach(System.out::println);
4.2 事件监听
不使用 Lambda 表达式
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
//handle the event
}
});
使用 Lambda 表达式,需要编写多条语句时用花括号包围起来:
button.addActionListener(e -> {
});
4.3 Predicate接口
java.util.function 包中的 Predicate 接口可以很方便地用于过滤。如果你需要对多个对象进行过滤并执行相同的处理逻辑,那么可以将这些相同的操作封装到 filter 方法中,由调用者提供过滤条件,以便重复使用。
不使用 Predicate 接口,对于每一个对象,都需要编写过滤条件和处理逻辑
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<String> words = Arrays.asList("a", "ab", "abc");
numbers.forEach(x -> {
if (x % 2 == 0) {
//process logic
}
})
words.forEach(x -> {
if (x.length() > 1) {
//process logic
}
})
使用 Predicate 接口,将相同的处理逻辑封装到 filter 方法中,重复调用:
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<String> words = Arrays.asList("a", "ab", "abc");
filter(numbers, x -> (int)x % 2 == 0);
filter(words, x -> ((String)x).length() > 1);
}
public static void filter(List list, Predicate condition) {
list.forEach(x -> {
if (condition.test(x)) {
//process logic
}
})
}
filter 方法也可写成:
public static void filter(List list, Predicate condition) {
list.stream().filter(x -> condition.test(x)).forEach(x -> {
//process logic
})
}
4.4 Map映射
使用 Stream 对象的 map 方法将原来的列表经由 Lambda 表达式映射为另一个列表,并通过 collect 方法转换回 List 类型:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> mapped = numbers.stream().map(x -> x * 2).collect(Collectors.toList());
mapped.forEach(System.out::println);
4.5 Reduce聚合
reduce 操作,就是通过二元运算对所有元素进行聚合,最终得到一个结果。例如使用加法对列表进行聚合,就是将列表中所有元素累加,得到总和。
因此,我们可以为 reduce 提供一个接收两个参数的 Lambda 表达式,该表达式就相当于一个二元运算:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream().reduce((x, y) -> x + y).get();
System.out.println(sum);
代替 Runnable
以创建线程为例,使用 Runnable 类的代码如下:
Runnable r = new Runnable() {
@Override
public void run() {
//to do something
}
};
Thread t = new Thread(r);
t.start();
使用 Lambda 表达式:
Runnable r = () -> {
//to do something
};
Thread t = new Thread(r);
t.start();
或者使用更加紧凑的形式:
Thread t = new Thread(() -> {
//to do something
});
t.start;
t();
System.out.println(sum);
代替 Runnable
以创建线程为例,使用 Runnable 类的代码如下:
```java
Runnable r = new Runnable() {
@Override
public void run() {
//to do something
}
};
Thread t = new Thread(r);
t.start();
使用 Lambda 表达式:
Runnable r = () -> {
//to do something
};
Thread t = new Thread(r);
t.start();
或者使用更加紧凑的形式:
Thread t = new Thread(() -> {
//to do something
});
t.start;