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机制, 并行流)