Explorar o código

docs: 更新20260803课堂笔记及README,同步代码变更——新增Lambda表达式与函数式接口知识点(Demo04标准格式与三要素+Swimming函数式接口+SwimmingTest匿名内部类vs Lambda三种实现方式/方法参数传递与变量接收)并补充随堂练习与拓展阅读

WanJL hai 3 semanas
pai
achega
bbca991af8

+ 2 - 2
README.md

@@ -37,7 +37,7 @@
 | 2026-07-29 | [包装类(Wrapper Classes)+ 集合框架入门(Collection Framework)+ 泛型(Generics):基本类型与包装类对应关系、装箱与拆箱、自动装箱/拆箱、包装类优势、缓存机制、Bean 类应用;集合 vs 数组、体系结构(Collection/List/Set/Map)、线性表数据结构(栈/队列/数组/链表)、ArrayList 底层实现详解(默认容量10、扩容机制、三个构造方法、size vs capacity、trimToSize/ensureCapacity/grow 1.5倍扩容公式、位运算符 >> <<)、ArrayList 常用方法速查;泛型概念与好处、泛型定义格式、通配符 ? / ? extends T、自定义泛型类、有界类型参数、练习参考答案(Student toString/equals/hashCode、泛型 vs 原始类型)](./课堂笔记/01-JavaSE基础-笔记/20260729-笔记.md) |
 | 2026-07-30 | [List.of / LinkedList / 自定义链表 / ArrayList 练习](./课堂笔记/01-JavaSE基础-笔记/20260730-笔记.md) |
 | 2026-07-31 | [LinkedList 多接口形态(List/Queue/Deque)+ Iterator 迭代器 + Map集合(入门/遍历/底层原理)+ 二叉树(二叉搜索树/平衡二叉树/红黑树)](./课堂笔记/01-JavaSE基础-笔记/20260731-笔记.md) |
-| 2026-08-03 | [比较器排序:Comparable 自然排序 / Comparator 比较器排序 + 集合工具类 Collections + 可变参数 Varargs + 20260731 课后作业解析(Map 操作与遍历、异常处理综合、匿名内部类 Comparator 排序)](./课堂笔记/01-JavaSE基础-笔记/20260803-笔记.md) |
+| 2026-08-03 | [比较器排序:Comparable 自然排序 / Comparator 比较器排序 + 集合工具类 Collections + 可变参数 Varargs + Lambda 表达式(函数式接口)+ 20260731 课后作业解析(Map 操作与遍历、异常处理综合、匿名内部类 Comparator 排序)](./课堂笔记/01-JavaSE基础-笔记/20260803-笔记.md) |
 
 ## 二、授课代码
 
@@ -61,7 +61,7 @@
 | 2026-07-29 | 包装类 + 集合框架入门 + 泛型(Generics):装箱/拆箱、自动装箱/拆箱、包装类在 Bean 中的应用;集合 vs 数组、体系结构、线性表数据结构、ArrayList 底层实现详解(默认容量10、扩容机制、三个构造方法、size vs capacity、trimToSize/ensureCapacity/grow 1.5倍扩容公式、位移运算符)、ArrayList 常用方法速查;泛型概念与好处、定义格式、通配符、自定义泛型类、有界类型参数、练习参考答案(Student 类重写 toString/equals/hashCode、泛型 vs 原始类型) | `c260729` | [`course/packaging`](./授课代码/c260729/src/course/packaging/) / [`course/collection`](./授课代码/c260729/src/course/collection/) / [`exercises/exercise01`](./授课代码/c260729/src/exericse/exericse01/) / [`exercises/exercise02`](./授课代码/c260729/src/exericse/exericse02/) |
 | 2026-07-30 | List.of() 不可变集合 + LinkedList 双链表理论 + 手写单链表 MyLinked + Student 课程管理练习 (ArrayList 常用操作) + 课后作业回顾手写 MyArrayList | `c260730` | [`course`](./授课代码/c260730/src/course/) / [`exericse/exericse01`](./授课代码/c260730/src/exericse/exericse01/) / [`homework0729/p4`](./授课代码/c260730/src/homework0729/p4/) |
 | 2026-07-31 | LinkedList 多接口形态(List / Queue / Deque)+ Iterator 迭代器遍历(ArrayList/LinkedList 迭代器)+ Map集合:入门(HashMap:put/keySet/values/containsKey)、遍历(keySet+get / entrySet)、HashMap底层原理(数组+链表/红黑树、hashCode/equals、5个关键常量)+ 二叉树(二叉搜索树/平衡二叉树AVL/红黑树规则与旋转)+ 随堂练习参考解答(自定义Key/词频统计) | `c260731` | [`course`](./授课代码/c260731/src/course/) / [`exericse/exericse01`](./授课代码/c260731/src/exericse/exericse01/) / [`exericse/exericse02`](./授课代码/c260731/src/exericse/exericse02/) |
-| 2026-08-03 | 比较器排序:TreeSet/TreeMap 有序集合、Comparable 自然排序(course/Student implements Comparable、compareTo 按年龄二次比较姓名)、Comparator 比较器排序(course/Demo01:TreeSet 构造传入匿名内部类 Comparator);集合工具类 Collections(course/Demo02:sort/sort+Comparator/reverse/binarySearch/max/min/unmodifiableList/shuffle/fill/swap/rotate/replaceAll + List.of 快速创建集合);可变参数 Varargs(course/Demo03:add(int... a) 参数个数可变、本质即数组、可变参数必须放最后);20260731 课后作业解析:Map 集合基本操作与遍历(homework0731/p2_map)、异常处理综合(homework0731/p4_exception:自定义异常 InvalidScoreException + 多 catch 块 + 输入校验)、匿名内部类 Comparator 排序(homework0731/p5_sort:Collections.sort 按年龄升序/成绩降序 Double.compare);随堂练习参考解答(exericse/exericse02:EmployeeSystem 员工管理,compareTo 薪资降序+工号、equals/hashCode 重写、匿名内部类按姓名排序) | `c260803` | [`course`](./授课代码/c260803/src/course/) / [`exericse/exericse02`](./授课代码/c260803/src/exericse/exericse02/) / [`homework0731/p2_map`](./授课代码/c260803/src/homework0731/p2_map/) / [`homework0731/p4_exception`](./授课代码/c260803/src/homework0731/p4_exception/) / [`homework0731/p5_sort`](./授课代码/c260803/src/homework0731/p5_sort/) |
+| 2026-08-03 | 比较器排序:TreeSet/TreeMap 有序集合、Comparable 自然排序(course/Student implements Comparable、compareTo 按年龄二次比较姓名)、Comparator 比较器排序(course/Demo01:TreeSet 构造传入匿名内部类 Comparator);集合工具类 Collections(course/Demo02:sort/sort+Comparator/reverse/binarySearch/max/min/unmodifiableList/shuffle/fill/swap/rotate/replaceAll + List.of 快速创建集合);可变参数 Varargs(course/Demo03:add(int... a) 参数个数可变、本质即数组、可变参数必须放最后);Lambda 表达式(course/Demo04 理论 + Swimming 函数式接口 + SwimmingTest:标准格式(参数)->{代码块}、三要素、匿名内部类 vs Lambda 三种实现方式、接口方法参数传递/变量接收);20260731 课后作业解析:Map 集合基本操作与遍历(homework0731/p2_map)、异常处理综合(homework0731/p4_exception:自定义异常 InvalidScoreException + 多 catch 块 + 输入校验)、匿名内部类 Comparator 排序(homework0731/p5_sort:Collections.sort 按年龄升序/成绩降序 Double.compare);随堂练习参考解答(exericse/exericse02:EmployeeSystem 员工管理,compareTo 薪资降序+工号、equals/hashCode 重写、匿名内部类按姓名排序) | `c260803` | [`course`](./授课代码/c260803/src/course/) / [`exericse/exericse02`](./授课代码/c260803/src/exericse/exericse02/) / [`homework0731/p2_map`](./授课代码/c260803/src/homework0731/p2_map/) / [`homework0731/p4_exception`](./授课代码/c260803/src/homework0731/p4_exception/) / [`homework0731/p5_sort`](./授课代码/c260803/src/homework0731/p5_sort/) |
 
 ## 三、课堂练习题
 

+ 34 - 0
授课代码/c260803/src/course/Demo04.java

@@ -0,0 +1,34 @@
+package course;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title Demo04
+ * @description Lambda表达式
+ * @create 2026/8/3
+ */
+public class Demo04 {
+    /*
+        Lambda表达式的标准格式:
+        格式:
+            (形式参数)->{代码块}
+            形式参数:如果形参有多个参数,那么参数之间使用逗号隔开,如果没有参数就留空。
+            -> :由英文中划线-和大于号组成,固定写法,代表指向动作。
+            {代码块}:就是我们具体要做的事情,固定的写法,就是以前我们写在方法体中的内容。
+        组成lambda表达式的三要素:
+        形式参数、箭头、代码块。
+
+        为什么要有lambda表达式,给我的感觉:
+            Java这门语言出现的很早,它针对各个版本的更新,其实正好踩中了高级编程语言规范化的整个起步阶段,直到顶峰。
+            但是后来随着各个语言的被开发和使用,特别是脚本类语言的使用越来越多,规范化由盛转衰,程序员开始抵触规范化,更喜欢具有更高自由度的写法。
+            Java被诟病的一大原因就是规范太多,太过冗长。
+            特别是JavaScript本来是刚开始的时候是为了蹭Java的热度,取得名字。
+            后来2010年前后,JavaScript大火、typeScript、Python、rust、go....
+            导致Java一致被人诟病,为了迎合新的市场需求,Java也开始求变,也引入了诸如:
+            lambda表达式、函数式接口、stream流等等操作
+            就像Java当初为了迎合C语言/C++程序员,而推出的基本数据类型一样,
+            然后又为了符合面向对象的特性,又搞出包装器类一样,特别拧巴。
+
+
+     */
+}

+ 12 - 0
授课代码/c260803/src/course/Swimming.java

@@ -0,0 +1,12 @@
+package course;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title Swimming
+ * @description
+ * @create 2026/8/3
+ */
+public interface Swimming {
+    void swim();
+}

+ 54 - 0
授课代码/c260803/src/course/SwimmingTest.java

@@ -0,0 +1,54 @@
+package course;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title SwimmingTest
+ * @description
+ * @create 2026/8/3
+ */
+public class SwimmingTest {
+    public static void getSwimming(Swimming s){
+        s.swim();
+    }
+    public static void main(String[] args) {
+        //实现Swimming接口并且重新swim()方法的方式,以前有两种:
+        //1、建立实现类,创建实现类对象。
+
+        //2、创建Swimming的匿名内部类,并且重写方法
+        getSwimming(new Swimming(){
+            @Override
+            public void swim() {
+                System.out.println("自由泳.....自由....免费");
+            }
+        });
+
+        //3、使用lambda表达式--其实就是另一种形式的匿名内部类
+        getSwimming(
+                ()->{
+                    System.out.println("蛙游.....呱....呱");
+                }
+        );
+
+
+        Swimming swimming = new Swimming() {
+
+            @Override
+            public void swim() {
+                System.out.println("自由泳.....自由....免费");
+            }
+        };
+        swimming.swim();
+
+        //lambda表达式
+        Swimming sw= ()->{
+            System.out.println("蛙游.....呱....呱");
+        };
+        //前面我们定义了格式规则:Swimming接口,并且里面只有一个需要重写的抽象方法。
+        //那么()能够指向的就只有一个需要重写的抽象方法,->指向的就是{代码块}也就是重写抽象方法的代码块内容
+
+        sw.swim();
+    }
+
+
+}

+ 116 - 12
课堂笔记/01-JavaSE基础-笔记/20260803-笔记.md

@@ -1,4 +1,4 @@
-# 20260803 课堂笔记 — 比较器排序(Comparable 自然排序 / Comparator 比较器排序)+ 集合工具类 Collections + 可变参数 Varargs + 20260731 课后作业解析
+# 20260803 课堂笔记 — 比较器排序(Comparable 自然排序 / Comparator 比较器排序)+ 集合工具类 Collections + 可变参数 Varargs + Lambda 表达式 + 20260731 课后作业解析
 
 - **日期**:2026-08-03
 - **项目**:`c260803`
@@ -15,11 +15,12 @@
 4. [返回值规则与 compareTo/equals 一致性的官方推荐](#4-返回值规则与-comparetoequals-一致性的官方推荐)
 5. [集合工具类 Collections](#5-集合工具类-collections)
 6. [可变参数 Varargs(参数个数可变)](#6-可变参数-varargs参数个数可变)
-7. [20260731 课后作业解析:Map 集合基本操作与遍历](#7-20260731-课后作业解析map-集合基本操作与遍历)
-8. [20260731 课后作业解析:异常处理综合(自定义异常)](#8-20260731-课后作业解析异常处理综合自定义异常)
-9. [20260731 课后作业解析:匿名内部类 Comparator 排序](#9-20260731-课后作业解析匿名内部类-comparator-排序)
-10. [随堂练习要点](#10-随堂练习要点)
-11. [拓展阅读](#11-拓展阅读)
+7. [Lambda 表达式(函数式接口)](#7-lambda-表达式函数式接口)
+8. [20260731 课后作业解析:Map 集合基本操作与遍历](#8-20260731-课后作业解析map-集合基本操作与遍历)
+9. [20260731 课后作业解析:异常处理综合(自定义异常)](#9-20260731-课后作业解析异常处理综合自定义异常)
+10. [20260731 课后作业解析:匿名内部类 Comparator 排序](#10-20260731-课后作业解析匿名内部类-comparator-排序)
+11. [随堂练习要点](#11-随堂练习要点)
+12. [拓展阅读](#12-拓展阅读)
 
 ---
 
@@ -366,7 +367,94 @@ public class Demo03 {
 
 ---
 
-## 7. 20260731 课后作业解析:Map 集合基本操作与遍历
+## 7. Lambda 表达式(函数式接口)
+
+### 概念
+
+**Lambda 表达式**是 JDK 8 引入的、**简化匿名内部类**的一种写法,让代码更简洁、自由度更高。
+
+**标准格式**:
+```java
+(形式参数) -> {代码块}
+```
+- **形式参数**:多个参数用逗号分隔;没有参数就留空(如 `()`)
+- **`->`**:由英文减号 `-` 和大于号 `>` 组成,固定写法,代表**指向动作**
+- **{代码块}**:具体要做的事情,就是以前写在**方法体**中的内容
+
+**三要素**:形式参数、箭头、代码块。
+
+**为什么要有 Lambda 表达式?**
+Java 常被诟病"规范太多、太过冗长"。随着 JavaScript / Python / Go 等更灵活的语言流行,Java 为了迎合新的市场需求也开始求变,引入了 Lambda 表达式、函数式接口、Stream 流等更简练的写法。
+
+### 函数式接口(Functional Interface)
+
+**只有一个抽象方法**的接口叫**函数式接口**。Lambda 表达式本质是**另一种形式的匿名内部类**,但**只能用于简化函数式接口**——因为接口里只有一个需要重写的抽象方法,Lambda 的 `()` 才不会有歧义。
+
+```java
+// 来源:course/Swimming.java
+// Swimming 接口只有一个抽象方法 swim() → 函数式接口
+public interface Swimming {
+    void swim();
+}
+```
+
+### 代码示例:三种实现方式的对比
+
+```java
+// 来源:course/SwimmingTest.java
+package course;
+
+public class SwimmingTest {
+    // 接收 Swimming 接口对象并调用其 swim() 方法
+    public static void getSwimming(Swimming s) {
+        s.swim();
+    }
+
+    public static void main(String[] args) {
+        // 实现 Swimming 接口并重写 swim() 方法,以前有两种方式:
+        // 1、建立实现类,创建实现类对象(此处略)
+
+        // 2、创建 Swimming 的匿名内部类,并重写方法
+        getSwimming(new Swimming() {
+            @Override
+            public void swim() {
+                System.out.println("自由泳.....自由....免费");
+            }
+        });
+
+        // 3、使用 Lambda 表达式 —— 其实就是另一种形式的匿名内部类
+        getSwimming(() -> {
+            System.out.println("蛙游.....呱....呱");
+        });
+
+        // 匿名内部类:用变量接收
+        Swimming swimming = new Swimming() {
+            @Override
+            public void swim() {
+                System.out.println("自由泳.....自由....免费");
+            }
+        };
+        swimming.swim();
+
+        // Lambda 表达式:用变量接收
+        Swimming sw = () -> {
+            System.out.println("蛙游.....呱....呱");
+        };
+        sw.swim();
+    }
+}
+```
+
+### 关键理解
+
+1. **Lambda = 匿名内部类的简化形式**:因为 `Swimming` 接口里**只有一个**需要重写的抽象方法,所以 `()` 能指向的就只有这一个抽象方法,`->` 指向的就是重写抽象方法的代码块内容。
+2. **使用前提**:Lambda 只能简化**函数式接口**(只有一个抽象方法),多抽象方法接口用 Lambda 会编译报错。
+3. **三要素对应**:`(形式参数)` → 重写方法的参数列表;`->` → 指向动作;`{代码块}` → 重写方法的方法体。
+4. **与匿名内部类的联系**:本节第 3 节 Comparator 正是用匿名内部类实现的,后续可以用 Lambda 进一步简化——如 `Collections.sort(list, (o1, o2) -> o1.getAge() - o2.getAge())`。
+
+---
+
+## 8. 20260731 课后作业解析:Map 集合基本操作与遍历
 
 ### 作业要求回顾
 
@@ -439,7 +527,7 @@ public class MapDemo {
 
 ---
 
-## 8. 20260731 课后作业解析:异常处理综合(自定义异常)
+## 9. 20260731 课后作业解析:异常处理综合(自定义异常)
 
 ### 作业要求回顾
 
@@ -514,7 +602,7 @@ public class ScoreStatisticsDemo {
 
 ---
 
-## 9. 20260731 课后作业解析:匿名内部类 Comparator 排序
+## 10. 20260731 课后作业解析:匿名内部类 Comparator 排序
 
 ### 作业要求回顾
 
@@ -596,7 +684,7 @@ public class Student {
 
 ---
 
-## 10. 随堂练习要点
+## 11. 随堂练习要点
 
 ### 练习一:自然排序(Comparable)与比较器排序(Comparator)对比
 
@@ -672,6 +760,20 @@ public class Student {
 2. 为什么有了可变参数还要方法重载?—— 参数**个数**不确定时用可变参数;参数**个数固定、类型不同**时重载更清晰
 3. 如果方法同时有固定参数和可变参数,顺序有什么要求?—— 可变参数必须写在**参数列表最后**,否则编译报错
 
+### 练习七:Lambda 表达式(简化匿名内部类)
+
+**核心步骤**:
+1. 定义一个**函数式接口** `Swimming`(只有一个抽象方法 `void swim()`)
+2. 用**匿名内部类**实现并调用 `swim()`
+3. 用 **Lambda 表达式**实现同样的功能:`() -> { System.out.println("..."); }`
+4. 分别用「方法参数传递」和「变量接收」两种方式使用 Lambda
+5. 对比匿名内部类与 Lambda 的代码量
+
+**思考**:
+1. Lambda 表达式的三要素是什么?—— 形式参数、箭头 `->`、代码块
+2. 为什么 Lambda 只能用在**只有一个抽象方法**的接口上?—— 只有一个待重写方法,`()` 才能唯一确定指向它
+3. 本节第 3 节的 Comparator 匿名内部类能否改写成 Lambda?—— 可以,如 `(o1, o2) -> o1.getAge() - o2.getAge()`,后续 Stream 也会大量使用
+
 ### 随堂练习参考解答(已提供代码)
 
 对应今日课堂练习的参考解答已写入授课代码:
@@ -739,7 +841,7 @@ treeSet = new TreeSet<>(new Comparator<Employee>() {
 
 ---
 
-## 11. 拓展阅读
+## 12. 拓展阅读
 
 ### 官方文档
 
@@ -750,6 +852,8 @@ treeSet = new TreeSet<>(new Comparator<Employee>() {
 - [Collections 工具类 (JDK 17)](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Collections.html)
 - [List.of() (JDK 17)](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html#of())
 - [可变参数 Varargs(Oracle 教程)](https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html#varargs)
+- [Lambda 表达式(Oracle 教程)](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html)
+- [函数式接口(Oracle 教程)](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#functional)
 - [RuntimeException (JDK 17)](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/RuntimeException.html)
 
 ### 推荐阅读
@@ -762,7 +866,7 @@ treeSet = new TreeSet<>(new Comparator<Employee>() {
 
 | 前置知识 | 当前知识 | 后续知识 |
 |----------|----------|----------|
-| 匿名内部类(0727) | Comparator 匿名内部类实现 | Lambda 表达式(函数式接口) |
+| 匿名内部类(0727) | Lambda 表达式 / 函数式接口 | Stream 流、方法引用 |
 | 集合体系与泛型(0729) | TreeSet / TreeMap 有序集合 | 红黑树底层(0731 已讲) |
 | HashMap 基本操作(0731) | Map 综合练习(keySet/entrySet 遍历) | Map 与 Set 的互转、分组统计 |
 | 异常处理(0728) | 自定义异常 + 多 catch 块 | 异常链、try-with-resources |