JDK8新特性:lambada、函数式编程、Stream流,这章我们来讲讲Stream流,建议lambada、函数式编程不熟悉的同学还是先补一下这俩,不然会一脸懵逼!
函数式编程:https://blog.csdn.net/weixin_44236420/article/details/106341734
Stream流
概念
Stream流是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。即,集合讲的是数据存储,流讲的是数据计算!
也可以理解为,流 就是运行在java中的sql语句。
一、 流的生成方法
- Collection接口的stream()或parallelStream()方法
- 静态的Stream.of()、Stream.empty()方法
- Arrays.stream(array, from, to)
- 静态的Stream.generate()方法生成无限流,接受一个不包含引元的函数
- 静态的Stream.iterate()方法生成无限流,接受一个种子值以及一个迭代函数
- Pattern接口的splitAsStream(input)方法
- 静态的Files.lines(path)、Files.lines(path, charSet)方法
- 静态的Stream.concat()方法将两个流连接起来
二、 流的Intermediate方法(中间操作)
- filter(Predicate)
将结果为false的元素过滤掉 - map(fun)
转换元素的值,可以用方法引元或者lambda表达式 - flatMap(fun)
若元素是流,将流摊平为正常元素,再进行元素转换 - limit(n)
保留前n个元素 - skip(n)
跳过前n个元素 - distinct()
剔除重复元素 - sorted()
将Comparable元素的流排序 - sorted(Comparator)
将流元素按Comparator排序 - peek(fun)
流不变,但会把每个元素传入fun执行,可以用作调试
三、 流的Terminal方法(终结操作)
约简操作
- max(Comparator)
- min(Comparator)
- count()
- findFirst()
返回第一个元素 - findAny()
返回任意元素 - anyMatch(Predicate)
任意元素匹配时返回true - allMatch(Predicate)
所有元素匹配时返回true - noneMatch(Predicate)
没有元素匹配时返回true - reduce(fun)
从流中计算某个值,接受一个二元函数作为累积器,从前两个元素开始持续应用它,累积器的中间结果作为第一个参数,流元素作为第二个参数 - reduce(a, fun)
a为幺元值,作为累积器的起点 - reduce(a, fun1, fun2)
与二元变形类似,并发操作中,当累积器的第一个参数与第二个参数都为流元素类型时,可以对各个中间结果也应用累积器进行合并,但是当累积器的第一个参数不是流元素类型而是类型T的时候,各个中间结果也为类型T,需要fun2来将各个中间结果进行合并
收集操作
- iterator()
- forEach(fun)
- forEachOrdered(fun)
可以应用在并行流上以保持元素顺序 - toArray()
- toArray(T[] :: new)
返回正确的元素类型 - collect(Collector)
- collect(fun1, fun2, fun3)
fun1转换流元素;fun2为累积器,将fun1的转换结果累积起来;fun3为组合器,将并行处理过程中累积器的各个结果组合起来
四、举例说明
题目1:给定一个长度为5的List集合,找出同时满足下列需求的的数据:
1.ID为偶数;
2.年龄大于24;
3.用户名转为大写;
4.用户名倒叙排列;
5.拿到第一个用户名。
User u1 = new User(1,"a",23);
User u2 = new User(2,"b",24);
User u3 = new User(3,"c",25);
User u4 = new User(4,"d",26);
User u5 = new User(6,"e",27);
List<User> list = Arrays.asList(u1,u2,u3,u4,u5);
//
String collect = list.stream()//集合转换为流
.filter(u -> {
return u.getID() % 2 == 0;
})//1.过滤器,取出ID为偶数的User
.filter(u -> {
return u.getAge() > 24;
})//2.过滤器,取出年龄大于24的User
.map(u -> {
return u.getUserName().toUpperCase();
})//3.转换元素的值,小写改大写
.sorted((c1, c2) -> {
return c2.compareTo(c1);
})//4.自定义排序
.limit(1)//5.只取一个数据
.collect(Collectors.joining());//再将流转换为字符串
System.out.println(collect);
题目2:将List<KpSpecialTaskSchedule`>进行排序,先按照unid升序,在unid相同的情况下根据order降序排序,在unid和order相同的情况下再根据rank升序排序
list2 = list.stream()
.sorted(Comparator.comparing(KpSpecialTaskSchedule::getScheduleUnid)
.thenComparing(KpSpecialTaskSchedule::getScheduleOrder).reversed()
.thenComparing(KpSpecialTaskSchedule::getRank)).collect(Collectors.toList());