Stream 自己本身不存储元素
Stream 不会改变元对象,但是他会返回一个持有结果的新Stream
Stream 操作是延时执行的,意味着需要结果时才执行
Stream执行流程
1 | 执行流程: 实例化 ==> 中间操作 ==> 终止操作 |
中间操作往往是一个操作链
一旦终止操作,就开始执行中间操作链,并产生结果。【延时执行,终止操作触发执行】
为了测试方便,这里写一个学生工具类StudentData.java,用来获取测试数据
1 | public class StudentData { |
1 | List<Student> list = StudentData.getList(); |
1 | int[] arr = new int[]{1,2,3,4,5}; |
1 | Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5); |
1 |
|
为了展示效果,这里用到了终止操作forEach(Consumer c),来打印生成的流,输出如下:
1 | 0.4110376914730558 |
1 |
|
输出如下:
1 | 0 |
从流中筛选需要的元素
1 | List<Student> list = StudentData.getList(); |
输出结果如下:
1 | Student{id=1004, name='赵六', age=42, salary=30000.0} |
从stream中获取指定大小的stream,可以类比sql中的LIMIT
1 |
|
输出如下:
1 | Student{id=1001, name='张三', age=34, salary=50000.0} |
从stream中跳过指定个数后获取stream
1 |
|
输出结果如下:
1 | Student{id=1003, name='王五', age=14, salary=600.0} |
**注意:**当跳过的个数超过stream中元素个数,返回空流
1 |
|
执行此代码无任何输出,因为此时生成的流为空
去重,根据stream中元素自己的hashcode()和equals()进行判断,效果可以类比sql中的DISTINCT
1 |
|
输出结果
1 | Student{id=1001, name='张三', age=34, salary=50000.0} |
去重后仅保留一个Tony对象
映射就是 a -> b 的过程,比如把水放进冰箱一段时间就会变成冰块,把水果放进榨汁机榨汁就会变成果汁等等,这些都是映射,只不过他们的映射规则不同。
在Stream中映射有两种
1 | 将一个流中元素转换成其他形式,或者提取其中信息,最终产生一个新的流 |
举个例子说明下:
**信息提取:**提取流中前3个元素的姓名属性, 映射成新的元素,最终生成一个新的流,
为了好理解,这里用了终止操作forEach(),并将Stream实例化、中间操作、终止操作分开写。
1 |
|
输出信息为:
1 | 张三 |
可以看到经过了map,原本的Student流最终映射为String流
再举个例子:
**格式转换:**截取流中前三个元素的姓名和年龄,产生一个新的字符串,格式为姓名:年龄,以次产生一个新的流
1 |
|
打印结果如下:
1 | 张三 : 34 |
可以看到了,通过map,将Student流映射成指定格式的String流
1 | 接收一个函数作为映射规则,该函数把流中的每个元素都转换成一个新的流,最后再把这些流连接成一个流 |
说人话就是,flatmap会把每一个元素都映射成一个流,最终把多个流整合成一个流
举个例子
将这个字符串数组创建的Stream中的每个元素都用,分割后生成一个流,最终整合为一个完整的流
1 | String[] strings = {"a","b,c,d","A,B"}; |
输出结果:
1 | a |
可能你觉得map与flatmap好像没啥区别,都是在映射,都是把一个流变成另一个流
但其实大有不同!!!
先看两个Api的参数
1 |
|
很明显flatMap的返回值R是Stream类型,这正对应了之前说的flatMap会把每个元素转换成Stream
如果把上一个例子中的flatmap换成map,试试会如何
1 | String[] strings = {"a","b,c,d","A,B"}; |
输出结果:
1 | java.util.stream.ReferencePipeline$Head@1963006a |
打印了3个对象,说明使用了map之后,最终生成的流中的3个元素都是流,并没有像flatmap进行整合操作
简单的总结下就如下:
1 | map: 1个流 ----> 1个流 |
Stream中间操作中有两种排序
1 |
|
输出结果
1 | 1 |
自定义排序,参数即为排序规则
1 |
|
输出结果
1 | Student{id=1003, name='王五', age=14, salary=600.0} |
Stream 自己本身不存储元素
Stream 不会改变元对象,但是他会返回一个持有结果的新Stream
Stream 操作是延时执行的,意味着需要结果时才执行
Stream执行流程
1 | 执行流程: 实例化 ==> 中间操作 ==> 终止操作 |
中间操作往往是一个操作链
一旦终止操作,就开始执行中间操作链,并产生结果。【延时执行,终止操作触发执行】
为了测试方便,这里写一个学生工具类StudentData.java,用来获取测试数据
1 | public class StudentData { |
1 | List<Student> list = StudentData.getList(); |
1 | int[] arr = new int[]{1,2,3,4,5}; |
1 | Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5); |
1 |
|
为了展示效果,这里用到了终止操作forEach(Consumer c),来打印生成的流,输出如下:
1 | 0.4110376914730558 |
1 |
|
输出如下:
1 | 0 |
从流中筛选需要的元素
1 | List<Student> list = StudentData.getList(); |
输出结果如下:
1 | Student{id=1004, name='赵六', age=42, salary=30000.0} |
从stream中获取指定大小的stream,可以类比sql中的LIMIT
1 |
|
输出如下:
1 | Student{id=1001, name='张三', age=34, salary=50000.0} |
从stream中跳过指定个数后获取stream
1 |
|
输出结果如下:
1 | Student{id=1003, name='王五', age=14, salary=600.0} |
**注意:**当跳过的个数超过stream中元素个数,返回空流
1 |
|
执行此代码无任何输出,因为此时生成的流为空
去重,根据stream中元素自己的hashcode()和equals()进行判断,效果可以类比sql中的DISTINCT
1 |
|
输出结果
1 | Student{id=1001, name='张三', age=34, salary=50000.0} |
去重后仅保留一个Tony对象
映射就是 a -> b 的过程,比如把水放进冰箱一段时间就会变成冰块,把水果放进榨汁机榨汁就会变成果汁等等,这些都是映射,只不过他们的映射规则不同。
在Stream中映射有两种
1 | 将一个流中元素转换成其他形式,或者提取其中信息,最终产生一个新的流 |
举个例子说明下:
**信息提取:**提取流中前3个元素的姓名属性, 映射成新的元素,最终生成一个新的流,
为了好理解,这里用了终止操作forEach(),并将Stream实例化、中间操作、终止操作分开写。
1 |
|
输出信息为:
1 | 张三 |
可以看到经过了map,原本的Student流最终映射为String流
再举个例子:
**格式转换:**截取流中前三个元素的姓名和年龄,产生一个新的字符串,格式为姓名:年龄,以次产生一个新的流
1 |
|
打印结果如下:
1 | 张三 : 34 |
可以看到了,通过map,将Student流映射成指定格式的String流
1 | 接收一个函数作为映射规则,该函数把流中的每个元素都转换成一个新的流,最后再把这些流连接成一个流 |
说人话就是,flatmap会把每一个元素都映射成一个流,最终把多个流整合成一个流
举个例子
将这个字符串数组创建的Stream中的每个元素都用,分割后生成一个流,最终整合为一个完整的流
1 | String[] strings = {"a","b,c,d","A,B"}; |
输出结果:
1 | a |
可能你觉得map与flatmap好像没啥区别,都是在映射,都是把一个流变成另一个流
但其实大有不同!!!
先看两个Api的参数
1 |
|
很明显flatMap的返回值R是Stream类型,这正对应了之前说的flatMap会把每个元素转换成Stream
如果把上一个例子中的flatmap换成map,试试会如何
1 | String[] strings = {"a","b,c,d","A,B"}; |
输出结果:
1 | java.util.stream.ReferencePipeline$Head@1963006a |
打印了3个对象,说明使用了map之后,最终生成的流中的3个元素都是流,并没有像flatmap进行整合操作
简单的总结下就如下:
1 | map: 1个流 ----> 1个流 |
Stream中间操作中有两种排序
1 |
|
输出结果
1 | 1 |
自定义排序,参数即为排序规则
1 |
|
输出结果
1 | Student{id=1003, name='王五', age=14, salary=600.0} |