![](https://img2023.cnblogs.com/blog/3076680/202301/3076680-20230127075603314-77787299.png)
1. 外部迭代
1.1. for循环是一个封装了迭代的语法糖
1.1.1. 本质上来讲是一种串行化操作
1.2. 很难抽象出不同操作
![](https://img2023.cnblogs.com/blog/3076680/202301/3076680-20230127075643083-525455157.png)
2. 内部迭代
2.1. 内部迭代中的相应接口:Stream
2.2. 和Iterator类似,Stream是一种内部迭代方式
2.3. 内部迭代将更多控制权交给了集合类
![](https://img2023.cnblogs.com/blog/3076680/202301/3076680-20230127075652366-235823282.png)
3. Stream
3.1. 理想方式
3.1.1. 形成一个惰性求值的链,最后用一个及早求值的操作返回想要的结果
3.2. Stream工厂是更好的选择
3.2.1. 仅暴露一个Stream接口,都不会影响内部的List或Set
3.3. 用函数式编程方式在集合类上进行复杂操作的工具
3.4. 惰性求值方法
3.4.1. 最终不产生新集合的方法
3.5. 及早求值方法
3.5.1. 最终会从Stream产生值的方法
3.6. 判断标准
3.6.1. 返回值是Stream
3.6.2. 返回值是另一个值或为空
4. 常用的流操作
4.1. of方法
4.1.1. 使用一组初始值生成新的Stream
4.2. collect(toList())方法
4.2.1. 由Stream里的值生成一个列表
4.2.2. 一个及早求值操作
4.3. map
4.3.1. 将一个流中的值转换成一个新的流
4.3.2. 一个函数可以将一种类型的值转换成另外一种类型
4.3.3. 参数和返回值不必属于同一种类型
4.3.4. 必须是Function接口的一个实例
4.3.4.1. Function接口是只包含一个参数的普通函数接口
4.4. flatMap
4.4.1. 可用Stream替换值,然后将多个Stream连接成一个Stream
4.4.2. 调用stream方法,将每个列表转换成Stream对象,其余部分由flatMap方法处理
4.4.3. Function接口
4.4.3.1. 方法的返回值限定为Stream类型
4.5. filter
4.5.1. 遍历数据并检查其中的元素
4.5.2. 值为true的元素被保留下来
4.5.3. Predicate接口
4.6. reduce
4.6.1. 实现从一组值中生成一个值
4.6.2. count方法
4.6.3. max和min
4.6.3.1. 返回Optional对象
4.6.3.1.1. 代表一个可能存在也可能不存在的值
4.6.3.2. Comparator对象
4.6.3.2.1. 静态方法comparing
4.6.3.2.2. 有且只有一个抽象方法
4.6.3.2.3. 实际上是一个函数接口
5. 多次调用流操作缺点
5.1. 代码可读性差,样板代码太多,隐藏了真正的业务逻辑
5.2. 效率差,每一步都要对流及早求值,生成新的集合
5.3. 代码充斥一堆垃圾变量,它们只用来保存中间结果
5.4. 难于自动并行化处理
6. 高阶函数
6.1. 接受另外一个函数作为参数,或返回一个函数的函数
6.2. 函数的参数列表里包含函数接口,或该函数返回一个函数接口
6.3. 没有副作用的函数不会改变程序或外界的状态
6.3.1. 给变量赋值是一种副作用
6.3.2. 向控制台输出了信息是一种副作用
6.3.3. 获取值使用户更容易写出没有副作用的代码
6.3.4. Lambda表达式传给Stream上的高阶函数,都应该尽量避免副作用
6.3.5. 唯一的例外是forEach方法,它是一个终结方法
posted @
2023-01-27 07:57
躺柒
阅读(
71)
评论()
编辑
收藏
举报