Stream流式计算
一、准备工作
package top.ptcc9.pojo;
import java.util.ArrayList;
import java.util.List;
/**
* @Author HE LONG CAN
* @Description:
* @Remark:
* @Date: 2020/10/21 18:09
* @Company: http://www.ptcc9.top
*/
public class User {
private Integer id;
private String name;
private Integer age;
private String sex;
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public User(Integer id, String name, Integer age, String sex) {
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
}
public static List<User> getList(){
List<User> userList = new ArrayList<>();
userList.add(new User(1,"张三",18,"男"));
userList.add(new User(2,"李四",24,"男"));
userList.add(new User(3,"王五",16,"女"));
userList.add(new User(4,"小六",27,"男"));
userList.add(new User(5,"王麻子",12,"女"));
userList.add(new User(6,"小七",12,"男"));
return userList;
}
}
2. 初体验
需求:取出userList里所有的id,生成一个新的list。
① java1.8之前的做法
List<Integer> userIdList = new ArrayList<>();
//在java1.8之前,我们想要取出userList里所有的用户id,首先想到的是遍历:
for (User user : userList) {
userIdList.add(user.getId());
}
② 使用Lambda表达式
//使用lambda表达式
userList.forEach((user) -> userIdList.add(user.getId()));
③ 使用Stream流式计算
//使用Stream流式计算
List<Integer> collect = userList.stream().map(User::getId).collect(Collectors.toList());
二、怎么玩
1. filter
使用场景:我们希望筛选出某些复合条件的项。
List<User> list = User.getList();
//筛选所有年龄 >= 18 的人
List<User> collect = list.stream().filter(user -> user.getAge() >= 18).collect(Collectors.toList());
collect.forEach(user -> System.out.println(user));
运行结果:
2. distinct
使用场景:当我们想获得所有的不重复的字段。
List<User> list = User.getList();
//获得所有年龄(不重复)
List<Integer> collect = list.stream().map(User::getAge).distinct().collect(Collectors.toList());
System.out.println(collect);
运行结果:
3. limit
使用场景:当我们想从结果集中选取前n个时。
List<User> list = User.getList();
//1.过滤出所有年龄为偶数的用户
//2.保留前两个记录
List<User> collect = list.stream().filter(user -> user.getAge() % 2 == 0).limit(2).collect(Collectors.toList());
collect.forEach(user -> System.out.println(user));
4. sorted
使用场景:排序。
List<User> list = User.getList();
//由小到大
List<User> collect = list.stream().sorted((s1,s2) -> s1.getAge() - s2.getAge()).collect(Collectors.toList());
collect.forEach(user -> System.out.println(user));
5. skip
使用场景:跳过n个元素后再输出。
List<User> list = User.getList();
//跳过前两个用户
List<User> collect = list.stream().skip(2).collect(Collectors.toList());
collect.forEach(System.out::println);
运行结果:
6. map
① 普通获取属性
例如:获取所有年龄是偶数的用户的姓名。
List<User> list = User.getList();
//获取所有年龄是偶数的用户的姓名。
List<String> collect = list.stream().filter(user -> user.getAge() % 2 == 0).map(User::getName).collect(Collectors.toList());
collect.forEach(System.out::println);
② 特殊操作
//获取所有年龄是偶数的用户的年龄之和。
list.stream().filter(user -> user.getAge() % 2 == 0).mapToInt(User::getAge).sum();
7. flatMap
flatMap与map的区别在于flatMap是将一个流中的每个值都转成了一个个流,然后再将这些流扁平化成为一个流。
举例说明:假设我们有一个字符串String[] strs = {"hello","world"},我们希望输出构成这一数组的所有非重复字符。
那我们分别使用map和flatMap实现如下。
① map
略
② flatMap
略
8. allMatch
用户判断是否全部满足条件。
List<User> list = User.getList();
//判断list中的所有用户的年龄是否都大于18岁
boolean result = list.stream().allMatch(user -> user.getAge() > 18);
System.out.println(result);
9. anyMatch
判断是否存在一项满足。
List<User> list = User.getList();
//判断是否存在一个用户的年龄大于24岁
boolean result = list.stream().anyMatch(user -> user.getAge() > 24);
System.out.println(result);
10. noneMatch
判断是否都不满足。
11. findFirst
找到第一个符合条件的项。
List<User> list = User.getList();
//找到第一个满足filter条件的项
User user1 = list.stream().filter(user -> user.getAge() > 18).findFirst().get();
System.out.println(user1);
12. findAny
返回任意一个满足条件的项。
List<User> list = User.getList();
//找到任意一个满足filter条件的项
User user1 = list.stream().filter(user -> user.getAge() > 18).findAny().get();
System.out.println(user1);
findAny在找不到时会出现异常,这时使用 .orElse来处理找不到的情况。
13. Collectors.方法
counting
maxBy 、minBy
summingInt、summingLong、summingDouble
averageInt、averageLong、averageDouble
joining:字符串拼接,在结果之间插入
String names = list.stream().map(User::getName).collect(Collectors.joining(","));