# 阶段四:Java 8 新特性 —— Lambda 与 Stream 流 —— 核心知识点总纲 > 本阶段涵盖:**比较器排序与 Lambda、函数式编程与 Stream 流** > 细分文档:`按日细分/20260803-笔记.md`、`按日细分/20260804-笔记.md` > 学生需要重点理解、背诵、掌握的理论核心知识点。 --- ## 一、比较器排序(对应 08-03) ### 1. 有序集合的两种排序方式(必背) | 排序方式 | 实现 | 场景 | |----------|------|------| | **自然排序 Comparable** | 实体类实现 `Comparable`,重写 `compareTo(T o)` | 类设计期确定默认规则 | | **比较器排序 Comparator** | 创建集合时传入 `Comparator`,重写 `compare()` | 类已定稿、临时自定义排序 | - TreeSet / TreeMap 是有序集合(取出时排序过) - 能存入条件:实现 Comparable **或** 构造传入 Comparator ### 2. 返回值规则(必背,两种排序共用) | 返回值 | 含义 | 处理结果 | |--------|------|----------| | 负数 | 当前元素小 | 存左边 | | **0** | 与已有元素"重复" | **不存**(去重) | | 正数 | 当前元素大 | 存右边 | > **官方推荐**:compareTo == 0 时 equals 返回 true、hashCode 一致——排序/相等/哈希判定一致,去重才符合预期。 > ⚠️ 只用单个属性排序时,属性相同会"丢"元素 → 叠加**二次比较**(如先年龄后姓名)。 ### 3. 降序技巧 **交换 compare/compareTo 两个参数的位置即可降序**:`Double.compare(o.getSalary(), this.salary)` = 薪资降序。 ### 4. Collections 工具类(必背) | 方法 | 作用 | |------|------| | `sort(List)` | 自然升序(元素必须 Comparable) | | `sort(List, Comparator)` | 自定义排序 | | `reverse(List)` | 逆序 | | `binarySearch(List, key)` | 二分查找(**必须先排序**) | | `max/min(List)` | 最大/最小 | | `unmodifiableList(List)` | 转不可变集合 | | `shuffle/fill/swap/rotate/replaceAll` | 打乱/填充/交换/旋转/替换 | ### 5. 可变参数 Varargs(必背) - `int... a` **本质就是数组**(`int[] a`),方法内 foreach 遍历 - **必须放参数列表最后**;一个方法最多一个可变参数 ## 二、Lambda 表达式(对应 08-03) ### 1. 概念 **Lambda(JDK 8)= 简化匿名内部类**的写法。 **标准格式:** `(形式参数) -> {代码块}`(三要素:参数、箭头、代码块) ### 2. 函数式接口(必背) **只有一个抽象方法的接口**叫函数式接口。Lambda 只能用于函数式接口。 **JDK 内置函数式接口(java.util.function 包):** | 接口 | 形态 | |------|------| | `Supplier` | 无参有返回值 | | `Consumer` | 有参无返回值 | | `Function` | 有参有返回值 | | `Predicate` | 有参返回 boolean(断言) | ### 3. Lambda 省略模式(必背三条) 1. **参数类型可省略**(要么全写、要么全省) 2. **单参数可省小括号**:`(s) ->` → `s ->` 3. **单语句可省大括号/分号/return**:`(a, b) -> a + b` ### 4. Lambda vs 匿名内部类 - 匿名内部类:接口/抽象类/普通类都行、多抽象方法也能用、编译产生 .class - **Lambda:只能是接口、必须只有一个抽象方法、编译不产生 .class(运行期动态生成字节码)** ### 5. 典型应用 ```java Collections.sort(list, (o1, o2) -> o1.getAge() - o2.getAge()); TreeSet set = new TreeSet<>(Comparator.comparing(Employee::getName)); ``` ## 三、函数式编程思想(对应 08-04) **函数式编程**:把计算看作数学中的函数计算,程序由函数组合构成(而非语句序列)。 五大特点:不可变性、高阶函数、**函数组合**(核心)、无副作用、延迟求值。 > **Stream 流才是真正把函数式编程引入 Java。** ## 四、Stream 流 —— 三类方法(必背) | 类别 | 作用 | 特点 | |------|------|------| | **获取方法** | 创建流水线 | 起点(`.stream()`) | | **中间方法** | 流水线操作 | 返回新 Stream,**可链式调用** | | **终结方法** | 最后一个操作 | **只能有一个**,调用后流结束 | ### 1. 生成 Stream 的四种方式(必背) | 数据来源 | 生成方式 | |----------|----------| | Collection 集合 | `集合.stream()` | | Map 集合 | `map.keySet().stream()` / `map.values().stream()` | | 数组 | `Arrays.stream(数组)` | | 零散数据 | `Stream.of(T... values)`(可变参数) | > Map 不是 Collection 体系,需先转 Set/Collection 再 stream()。 ### 2. 中间操作方法(必背) | 方法 | 作用 | |------|------| | `filter(Predicate)` | 过滤 | | `limit(n)` | 截取前 n 个 | | `skip(n)` | 跳过前 n 个 | | `map(Function)` | 映射(元素转另一种类型) | | `concat(a, b)` | 合并两个流(**静态方法**) | | `distinct()` | 去重(依赖 equals) | > `limit + skip` 组合实现**分页**:`skip((pageNo-1)*pageSize).limit(pageSize)`。 ### 3. 方法引用(四种形式必背) | 形式 | 写法 | 示例 | |------|------|------| | 类的静态方法 | `类名::静态方法名` | `String::valueOf` | | 对象的实例方法 | `对象名::方法名` | `sb::append` | | 类的实例方法 | `类名::方法名` | `String::substring` | | 类的构造方法 | `类名::new` | `String::new` | > 使用前提:方法体只有一行代码,且抽象方法的**所有参数按顺序**传入被引用方法。 > `类名::方法名` 形式下,抽象方法**第一个参数**就是调用成员方法的对象。 ### 4. 终结操作方法(必背) | 方法 | 作用 | |------|------| | `forEach(Consumer)` | 遍历(参数是有参无返回值) | | `count()` | 计数(**返回 long**) | ### 5. 收集操作方法(必背) | 方法 | 收集目标 | |------|----------| | `Collectors.toList()` | List(**不可变**) | | `Collectors.toSet()` | Set(天然去重) | | `Collectors.toMap(keyMapper, valueMapper)` | Map(键必须唯一,冲突抛 IllegalStateException) | | `Stream.toList()` | List(不可变) | | `toArray()` | 数组 | ```java List nameList = list.stream().map(Student::getName).collect(Collectors.toList()); Map map = list.stream().collect(Collectors.toMap(s -> s.getId(), s -> s)); ``` ## 本阶段必须背诵的核心口诀 1. **Comparable 写进类、Comparator 传参临时换** 2. **compareTo 返回 0 = 重复不存;负数左、正数右** 3. **降序技巧 = 交换参数位置** 4. **可变参数本质是数组、必须放最后** 5. **Lambda 只能简化的函数式接口(只有一个抽象方法)** 6. **省略三规则**:类型可全省、单参省括号、单语句省大括号/分号/return 7. **Stream 三类方法**:获取 → 中间(可链式)→ 终结(只能一个) 8. **filter 过滤、map 映射、limit/skip 分页、distinct 去重** 9. **方法引用 `::` 四种形式**:静态/对象实例/类实例/构造 10. **collect 收集**:toList(不可变)、toSet(去重)、toMap(键唯一)