流Stream
用来以“做什么而非怎么做”的方式来处理集合
- 流并不存储元素,,这些元素可能存储在底层的集合中,或者是按需生成的。存储的是规则
- 流的操作不会修改其数据源,会生成新的流
- 流的操作时尽可能惰性执行的,知道需要结果时,操作才会执行,可以操作无限流
- 执行流的操作时不能修改背后的集合
创建流
有很多方法创建流
转换流
流的转换会产生一个新的流,它的元素来自前一个流中的元素。
filter、map、flatMap
抽取子流和组合流
其他流转换
约简操作(终结操作)
约简就是将流变成程序中使用的非流值。
Optional类型
Optional
- 获取Optional的值
- 消费Optional的值
- 管道化Optional
不适合使用Optional值的方式
- optional类型变量永远不应该为null
Stream.empty().findAny();会出现空指针异常
- 不要使用Optional类习惯的域(不要声明为属性和方法参数),因为其代价时额外多出来一个对象。在类的内部,使用null表示缺失的域更易于操作
- 不要在集合中防止optional对象,并且不要将它们用作map的key。
创建Optional的值
收集结果
收集到映射表中
分组和分区
下游收集器
groupingBy方法会产生一个映射表,它的每个值都是一个列表,如果想要以某种方式来处理这些列表,就需要提供一个下游收集器。
reduce
基本类型流
八大基本类型对应的有三种基本类型流
-
IntStream
-
LongStream
-
DoubleStream
-
一些可以返回基本类型流的类
并行流
注意点:
- 确保传递给并行流的任何函数操作都是安全的
- 如果对顺序没有要求,可以通过Stream.unordered()方法放弃排序,
- Stream.distinct方法会保留相同元素中的第一个,如果放弃排序后再执行,就会变成保留相同元素中的任意一个,这样可以提高并行效率
- limit方法类似,放弃排序后变成从流中取出任意的n个元素