Stream流式计算

 

一、准备工作

1. 编写实体类

 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;
 
     @Override
     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));

运行结果:

image-20201021194152113

2. distinct

使用场景:当我们想获得所有的不重复的字段。

List<User> list = User.getList();

//获得所有年龄(不重复)
List<Integer> collect = list.stream().map(User::getAge).distinct().collect(Collectors.toList());

System.out.println(collect);

运行结果:

image-20201021193225307

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);

运行结果:

image-20201021195127401

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();

image-20201021200426704

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.方法

  1. counting

  2. maxBy 、minBy

  3. summingInt、summingLong、summingDouble

  4. averageInt、averageLong、averageDouble

  5. joining:字符串拼接,在结果之间插入

 String names = list.stream().map(User::getName).collect(Collectors.joining(","));