Steam流
Steam流是java 8 版本新增的,配合同版本出现的Lambda表达式 ,给我们操作集合(Collection)提供了极大的便利。Steam流Steam流
Steam流是什么?
Java 中可以使用 java.util.Stream 对一个集合(实现了java.util.Collection接口的类)做各种操作,例如:求和、过滤、排序等等。这些操作可能是中间操作——返回一个 Stream 流,或者是终端操作——返回一个结果。
同时,流操作不会影响原来的集合,也不会存储数据,可以简单认为,流操作是把集合中的一个元素逐个复制放到一个首尾相接的流动的容器中进行相应的操作,操作结束,容器消失;下一次操作再重复上述过程,这也就是说Steam是延迟执行的。
Stream 流支持同步执行,也支持并发执行。如果我们直接获取 stream 流,得到的是同步执行的 stream 流;如果调用方法 parallelStream,则得到一个可以并发执行的 Stream 流。可以说Stream 流极大的提高开发效率,也可以使用它写出更加简洁明了的代码。
需要注意的是:Map不支持 Stream 流,但是它的 Key 和 Value 支持,因为它们实现了 Set 接口。
好处
它可以大幅减少我们的代码量,并且会返回新的列表,不会改变原来的列表。如果不用,写法肯定是for循环套for循环,再new新的list来回转,非常麻烦。
企业开发中常用的Stream流操作,经常使用
模拟数据
List<Student> stuList = new ArrayList<>();
stuList.add(new Student(1, "张三", 20,new BigDecimal(20)));
stuList.add(new Student(2, "李四", 22,new BigDecimal(30)));
stuList.add(new Student(3, "王五", 21,new BigDecimal(40)));
过滤filter
//过滤filter,只是过滤掉一些数据,例如只保存掉年龄大于20
List<Student> collect = stuList.stream().filter(student -> student.getAge() > 20).collect(Collectors.toList());
System.out.println("collect="+collect);
map
//map,是对内部数据进行修改,并且返回被操作的属性值,例如对年龄进行+1操作
List<Integer> collect1 = stuList.stream().map(student -> student.getAge() + 1).collect(Collectors.toList());
System.out.println("collect1="+collect1);
排序sorted正序
//排序sorted,例如根据年龄进行排序,正序
List<Student> collect2 = stuList.stream().sorted(Comparator.comparing(Student::getAge)).collect(Collectors.toList());
System.out.println("倒序:"+collect2);
排序sorted倒序
//排序sorted,例如根据年龄进行排序,倒序
List<Student> collect3 = stuList.stream().sorted(Comparator.comparing(Student::getAge).reversed()).collect(Collectors.toList());
System.out.println("倒序:"+collect3);
聚合操作
//先根据map取出某个属性,例如金额,进行累加reduce(BigDecimal.ZERO,BigDecimal::add),一般用于设计钱的事
BigDecimal allMoney = stuList.stream().map(Student::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println("allMoney="+allMoney);
将list中元素的对象属性取出转换成map,例如id作为key,name作为值,(k1,k2)->k1,意思是如果key相同取前面的,保证key不能重复
//将list中元素的对象属性取出转换成map,例如id作为key,name作为值,(k1,k2)->k1,意思是如果key相同取前面的,保证key不能重复
Map<Integer, String> collect4 = stuList.stream().collect(Collectors.toMap(Student::getId, Student::getName, (k1, k2) -> k1));
System.out.println("collect4="+collect4);
分组操作
//根据部门进行分组
Map<Integer, List<Student>> collect = stuList.stream().collect(Collectors.groupingBy(Student::getDeptId));
collect.forEach((k,v)->{
System.out.println("key="+k+" value="+v);
});
去重操作
//从集合中去除重复的学生名字
List<String> collect1 = stuList.stream().map(Student::getName).distinct().collect(Collectors.toList());
collect1.forEach(System.out::println);
统计操作
//统计每个部门的学生人数
Map<Integer, Long> collect2 = stuList.stream().collect(Collectors.groupingBy(Student::getDeptId, Collectors.counting()));
collect2.forEach((k,v)->{
System.out.println("key="+k+" value="+v);
});
组合操作
//获取年龄大于 30 的用户中用户名长度超过 5 的用户
List<Student> collect3 = stuList.stream().filter(student -> student.getAge() > 30).filter(student -> student.getName().length() > 5).collect(Collectors.toList());
System.out.println(collect3);
并行处理
//并行
List<Student> collect4 = stuList.parallelStream().filter(student -> student.getAge() > 30).filter(student -> student.getName().length() > 5).collect(Collectors.toList());
collect4.forEach(System.out::println);
连接操作
//将多个字符串列表合并成一个字符串
List<String> list = new ArrayList<>();
list.add("hello");
ArrayList<String> list1 = new ArrayList<>();
list1.add("world");
String collect = Stream.concat(list.stream(), list1.stream()).collect(Collectors.joining());
System.out.println(collect);
查找操作
//查找第一个满足条件的用户
Student student = stuList.stream().filter(student1 -> student1.getAge() > 10).findFirst().get();
System.out.println(student);
Lambda表达式
lambda表达式是为了简写代码的写法,将这种写法叫为Lambda表达式。
lambda表达式核心概念为 函数式接口、:: 、-> 等基本语法,可以大大减少代码量的编写,使代码更加简练漂亮。
1、只有一个抽象函数的接口,就是函数式接口 ;
2、:: 可以称之为域运算符,主要是用来获取方法;
3、-> 的语法为 (变量或参数)->{代码体},是匿名函数的写法。也叫变量和代码的分隔符 ;
4、当只获取一个方法属性的时候 :: 和 -> 可以通用。