1. Stream 的实现机制 (3.2)
这是理解流式编程(Stream API)的基础,核心在于区分操作的类型。
惰性求值 (Lazy Evaluation)
判断标准: 如果返回值仍然是 Stream。
特点: 操作不会立即执行,而是像构建流水线一样被记录下来,直到遇到终止操作。
示例:filter, map
及早求值 (Eager Evaluation)
判断标准: 如果返回值是另一个值(如 List, Integer)或为空 (void)。
特点: 会立即触发整个流水线的执行,产生最终结果。
示例:collect, count, forEach
2. 核心 Stream 操作详解 (3.3)
这是日常开发中使用频率最高的部分,涵盖了转换、聚合和排序。
2.1 转换与映射
map (一对一转换)
功能: 如果有一个函数可以将一种类型的值转换成另外一种类型,map 就可以使用该函数,将流中的值转换成一个新的流。
flatMap (一对多/扁平化)
功能: 可用 Stream 替换值,然后将多个 Stream 连接成一个 Stream。
场景: 处理嵌套列表或需要将多个结果合并时使用。
2.2 归约与聚合 (Reduction)
collect(toList())
由 Stream 里的值生成一个列表。这是一个典型的及早求值操作。
max / min
Stream API 提供的求最大值和最小值的操作,足以解决大多数极值问题。
reduce
功能: 实现从一组值中生成一个值(例如求和、拼接字符串)。
Lambda 参数: reduce 接受的 Lambda 表达式就是一个 reducer,它包含两个关键参数:
acc (Accumulator): 累加器(当前的累计结果)。
element: 传入 Stream 中的当前元素。
2.3 排序 (Sorting)
Comparator
为了让 Stream 对象按照特定规则(如曲目长度)排序,需要传递一个 Comparator 对象。
comparing 方法
Java 8 提供的新静态方法。
优势: 可以非常方便地提取键值来实现比较器(例如 Comparator.comparing(Track::getLength))。
3. 高级收集器与数据分组 (5.3)
这一部分主要涉及 Collectors 类,用于处理复杂的聚合逻辑。
partitioningBy (分区)
接受一个流,并将其分成两部分。
通常基于一个断言(Predicate,即返回 boolean 的函数),结果是 Map<Boolean, List<T>>。
groupingBy (分组)
概念类比: 类似于 SQL 中的 GROUP BY 操作。
功能: 在 Stream 类库中实现了数据分组,不再需要手动编写循环将元素放入 Map 中。
4. 集合 API 细节 (5.4)
Java 8 不仅引入了 Stream,还改进了原有的集合接口。
Map 的 forEach
变化: Map 接口新增了 forEach 方法。
参数: 接受一个 BiConsumer 对象(该对象接受两个参数:Key 和 Value,返回空)。
优势: 相比传统的 entrySet 遍历,代码更加简洁。
5. 并行化流操作 (6.3)
如何利用多核 CPU 提升性能。
实现方式
只需调用 parallelStream() 方法即可开启并行处理。
简便性: 除了方法名不同,剩余的代码逻辑与串行流(Sequential Stream)完全一致。
核心思考
笔记中提出了一个关键问题:“并行化运行基于流的代码是否比串行化运行更快?”
(注:这通常暗示并行流并非银弹,涉及数据量大小、装箱拆箱开销以及任务是否计算密集型等因素。)
总结与建议
这组笔记非常精准地覆盖了 Java 8 函数式编程的三个阶段:
怎么写(Stream API, Lambda, 常用操作)
怎么收(Collectors, reduce, Map更新)
怎么跑(Lazy机制, 并行流)
