Stream流的介绍
stream不存储数据,而是按照特定的规则对数据进行计算,一般会输出结果;
stream不会改变数据源,通常情况下会产生一个新的集合;
stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行。
对stream操作分为终端操作和中间操作,那么这两者分别代表什么呢?
终端操作:会消费流,这种操作会产生一个结果的,如果一个流被消费过了,那它就不能被重用的。
中间操作:中间操作会产生另一个流。因此中间操作可以用来创建执行一系列动作的管道。一个特别需要注意的点是:中间操作不是立即发生的。相反,当在中间操作创建的新流上执行完终端操作后,中间操作指定的操作才会发生。所以中间操作是延迟发生的,中间操作的延迟行为主要是让流API能够更加高效地执行。
stream不可复用,对一个已经进行过终端操作的流再次调用,会抛出异常。
前期准备
创建学生表 并简单构建一些数据
package com.test.Entity;
import lombok.Data;
@Data
public class Student {
/**
* 序号
*/
private Integer num;
/**
* 学生姓名
*/
private String name;
/**
* 学生分数
*/
private String city;
public Student() {
this.num = num;
this.name = name;
this.city = city;
}
public Student(Integer num, String name, String city) {
this.num = num;
this.name = name;
this.city = city;
}
}
private static List<Student> getStudentList (){
List<Student> userList = new ArrayList<>() ;
userList.add(new Student(1,"张三","上海")) ;
userList.add(new Student(2,"李四","北京")) ;
userList.add(new Student(3,"王五","北京")) ;
userList.add(new Student(4,"顺六","上海,杭州")) ;
return userList ;
}
fiter 过滤 输出序号num大于1的数据
studentsList.stream().filter(v -> v.getNum() > 1).forEach(System.out::println);
map:将现有的元素转换映射到对应的结果,输出学生所在城市;
studentsList.stream().map(v -> v.getName()+" 在 "+v.getCity()).forEach(System.out::println);
peek:对元素进行遍历处理,每个学生num加1输出;
studentsList.stream().peek(v -> v.setNum(v.getNum()+1)).forEach(System.out::println);
flatMap:数据拆分一对多映射,学生所在多个城市;
studentsList.stream().flatMap(v -> Arrays.stream(v.getCity().split(","))).forEach(System.out::println);
sorted:指定属性排序,根据学生num倒序输出;
studentsList.stream().sorted(Comparator.comparingInt(Student::getNum).reversed()).forEach(System.out::println);
distinct:去重,学生所在城市去重后输出;
studentsList.stream().map(Student::getCity).distinct().forEach(System.out::println);
skip & limit:截取,过滤后的数据跳过,截取第一条;
studentsList.stream().filter(v -> v.getNum()>1).skip(1).limit(1).forEach(System.out::println);
min:最小值,获取学生最小的num值;
studentsList.stream().min(Comparator.comparingInt(Student::getNum)).get().getNum();
max:最大值,获取学生最大的num值;
int max = studentsList.stream().max(Comparator.comparingInt(Student::getNum)).get().getNum();
sum:求和,对学生序号num进行累计求和;
int sum = studentsList.stream().mapToInt(Student::getNum).sum() ;
count:总数,id小于2的学生总数;
long count = studentsList.stream().filter(v -> v.getNum()<2).count();
foreach:遍历,输出北京相关的学生;
studentsList.stream().filter(v -> "北京".equals(v.getCity())).forEach(System.out::println);
findAny:查找符合条件的任意一个元素,获取一个北京学生;
Student getUser = studentsList.stream().filter(v -> "北京".equals(v.getCity())).findAny().get();
findFirst:获取符合条件的第一个元素;
Student getUser = studentsList.stream().filter(v -> "北京".equals(v.getCity())).findFirst().get();
anyMatch:匹配判断,判断是否存在深圳的学生;
boolean matchFlag = studentsList.stream().anyMatch(user -> "深圳".equals(user.getCity()));
allMatch:全部匹配,判断所有学生的城市不为空;
boolean matchFlag = studentsList.stream().allMatch(v -> StrUtil.isNotEmpty(v.getCity()));
noneMatch:全不匹配,判断没有学生的城市为空;
boolean matchFlag = studentsList.stream().noneMatch(v -> StrUtil.isEmpty(v.getCity()));
以上只是一些简单的方法 主要涉及Stream流的一些统计和判断相关的能力,实际运用完全不够。
收集
toList:将序号存放到List集合中;
List<Integer> idList = studentsList.stream().map(Student::getNum).collect(Collectors.toList()) ;
toMap:将用序号和Name以Key-Value形式存放到Map集合中;
Map<Integer,String> StudentMap = studentsList.stream().collect(Collectors.toMap(Student::getNum,Student::getName));
toSet:将学生所在城市存放到Set集合中;
Set<String> citySet = studentsList.stream().map(Student::getCity).collect(Collectors.toSet());
counting:符合条件的学生总数;
long count = studentsList.stream().filter(Student -> Student.getNum()>1).collect(Collectors.counting());
summingInt:对结果元素即序号求和;
Integer sumInt = studentsList.stream().filter(Student -> Student.getNum()>2).collect(Collectors.summingInt(Student::getNum)) ;
minBy:筛选元素中序号num最小的学生
Student maxId = studentsList.stream().collect(Collectors.minBy(Comparator.comparingInt(Student::getNum))).get() ;
joining:将学生所在城市,以指定分隔符链接成字符串;
String joinCity = studentsList.stream().map(Student::getCity).collect(Collectors.joining("||"));
groupingBy:按条件分组,以城市对学生进行分组;
Map<String,List<Student>> groupCity = studentsList.stream().collect(Collectors.groupingBy(Student::getCity));