Explorar el Código

docs: 更新20260729课堂笔记,同步代码变更——新增ArrayList底层实现详解:默认容量10、扩容机制、DEFAULTCAPACITY_EMPTY_ELEMENTDATA、三个构造方法、size vs capacity区别

WanJL hace 10 horas
padre
commit
19618eb719

+ 2 - 2
README.md

@@ -34,7 +34,7 @@
 | 2026-07-24 | [多态 + 多态中的转型 + 内部类:多态概念与前提、多态成员访问特点、向上转型/向下转型、instanceof类型判断、多态的好处(开闭原则)、抽象类与多态结合(Animal→Dog;Person→Student/Teacher综合案例)、Usb接口多态案例(NoteBook接入鼠标/猫)、内部类概念与使用场景、成员内部类、私有内部类设计原则](./课堂笔记/01-JavaSE基础-笔记/20260724-笔记.md) |
 | 2026-07-27 | [匿名内部类 + Java API 与 String 类 + Math + 日期时间:内部类三大分类、匿名内部类四种使用方式、综合案例(USB/餐具/学生排序/计算器/动物叫声);API概念、String内存模型/不可变性/可变字符串StringBuffer&StringBuilder/文本块TextBlock JDK15+/String常用方法大全;Math数学类常用方法;日期时间类(Date/LocalDate/LocalTime/LocalDateTime/DateTimeFormatter)](./课堂笔记/01-JavaSE基础-笔记/20260727-笔记.md) |
 | 2026-07-28 | [Java 异常处理:异常概念、Throwable 体系结构、编译期/运行时异常、JVM 默认处理、try-catch 多 catch 块、异常常用方法、finally 资源关闭、throws 抛出、鲁棒性;自定义异常、throw/throws;Object 类:equals/hashCode/toString 重写、Objects 工具类;课后作业回顾 — String 分割去重/统计、LocalDate 天数差计算](./课堂笔记/01-JavaSE基础-笔记/20260728-笔记.md) |
-| 2026-07-29 | [包装类(Wrapper Classes)+ 集合框架入门(Collection Framework):基本类型与包装类对应关系、装箱与拆箱、自动装箱/拆箱、包装类优势、缓存机制、Bean 类应用;集合 vs 数组、体系结构(Collection/List/Set/Map)、线性表数据结构(栈/队列/数组/链表)](./课堂笔记/01-JavaSE基础-笔记/20260729-笔记.md) |
+| 2026-07-29 | [包装类(Wrapper Classes)+ 集合框架入门(Collection Framework):基本类型与包装类对应关系、装箱与拆箱、自动装箱/拆箱、包装类优势、缓存机制、Bean 类应用;集合 vs 数组、体系结构(Collection/List/Set/Map)、线性表数据结构(栈/队列/数组/链表)、ArrayList 底层实现详解(默认容量10、扩容机制、三个构造方法、size vs capacity)](./课堂笔记/01-JavaSE基础-笔记/20260729-笔记.md) |
 
 ## 二、授课代码
 
@@ -55,7 +55,7 @@
 | 2026-07-24 | 多态概念与前提、多态成员访问特点、向上转型/向下转型、instanceof运算符、多态的好处(开闭原则)、抽象类+多态(Animal→Dog、Person→Student/Teacher→Test03.runPerson())、接口多态(Usb→Mouse/Cat→NoteBook)、内部类概念与使用场景 | `c260724` | [`course/polymorphism`](./授课代码/c260724/src/course/polymorphism/) / [`course/internalClass`](./授课代码/c260724/src/course/internalClass/) |
 | 2026-07-27 | 匿名内部类:内部类三大分类概念回顾、匿名内部类语法格式与本质、三种使用方式(多态接收变量赋值 / 方法参数传递 / 匿名对象直接调用)、配套接口/抽象类定义(Usb / Tableware / Compute / Sort)、综合案例(NoteBook USB设备 / Person 餐具 / 学生排序比较 / Calculator计算器 / Animal动物叫声);Java API:API概念、String类(内存模型/构造方法/==与equals/常用方法大全/不可变性)、可变字符串(StringBuffer/SringBuilder)、文本块TextBlock JDK15+;Math数学类;日期时间类(Date/LocalDate/LocalTime/LocalDateTime/DateTimeFormatter) | `c260727` | [`course/anonymousInternalClass`](./授课代码/c260727/src/course/anonymousInternalClass/) / [`course/api`](./授课代码/c260727/src/course/api/) / [`course/api/string`](./授课代码/c260727/src/course/api/string/) / [`course/api/math`](./授课代码/c260727/src/course/api/math/) / [`course/api/date`](./授课代码/c260727/src/course/api/date/) / [`exercise/exercise01`](./授课代码/c260727/src/exercise/exercise01/) / [`exercise/exercise06`](./授课代码/c260727/src/exercise/exercise06/) / [`exercise/exercise07`](./授课代码/c260727/src/exercise/exercise07/) / [`homework_0724/p2_myarray`](./授课代码/c260727/src/homework_0724/p2_myarray/) |
 | 2026-07-28 | 异常处理(Demo01~Demo04 + Person+AgeOutOfBoundsException) + Object类(Demo01+Person 重写equals/hashCode/toString) + 课后作业回顾(String工具 + 日期数学) + Exercises | `c260728` | [`course/api`](./授课代码/c260728/src/course/api/) / [`course/exception`](./授课代码/c260728/src/course/exception/) / [`homework260727`](./授课代码/c260728/src/homework260727/) / [`exercise/exercise01`](./授课代码/c260728/src/exercise/exercise01/) / [`exercise/exercise07`](./授课代码/c260728/src/exercise/exercise07/) |
-| 2026-07-29 | 包装类(Wrapper Classes):装箱与拆箱、自动装箱/拆箱、包装类在 Bean 类中的应用(Person + Demo01) + 集合框架入门(Collection Framework):集合 vs 数组、体系结构(Collection/List/Set/Map)、线性表数据结构(栈/队列/数组/链表) | `c260729` | [`course/packaging`](./授课代码/c260729/src/course/packaging/) / [`course/collection`](./授课代码/c260729/src/course/collection/) |
+| 2026-07-29 | 包装类(Wrapper Classes):装箱与拆箱、自动装箱/拆箱、包装类在 Bean 类中的应用(Person + Demo01) + 集合框架入门(Collection Framework):集合 vs 数组、体系结构(Collection/List/Set/Map)、线性表数据结构(栈/队列/数组/链表)、ArrayList 底层实现详解(默认容量10、扩容机制、三个构造方法、size vs capacity) | `c260729` | [`course/packaging`](./授课代码/c260729/src/course/packaging/) / [`course/collection`](./授课代码/c260729/src/course/collection/) |
 
 ## 三、课堂练习题
 

+ 43 - 1
授课代码/c260729/src/course/collection/Demo02.java

@@ -1,5 +1,7 @@
 package course.collection;
 
+import java.util.ArrayList;
+
 /**
  * @author WanJl
  * @version 1.0
@@ -30,12 +32,52 @@ public class Demo02 {
                 ArrayList:数组
                 LinkedList:队列、栈、链表
 
+            ArrayList:
+                本质是一个长度可变的数组,底层使用的是数组。
+                ArrayList 里面可以存储 null
+                和Vector差不多,但是不是线程同步的。性能更高一些。
 
+                ArrayList有一个参数 Capacity,容量会随着元素的增加而增加,并且会进行扩容。
+                ArrayList的默认初始容量为10
+                private static final int DEFAULT_CAPACITY = 10;
 
+                内部还有一个空的Object类型的数组
+                private static final Object[] EMPTY_ELEMENTDATA = {};
+                还有一个默认容量的空数组
+                private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
+                ArrayList中维护的底层数组就是elementData。
+                空数组没有任何元素插入的时候,就使用的数组容量是DEFAULTCAPACITY_EMPTY_ELEMENTDATA
+                但是,如果插入了一个元素,立马把elementData的容量扩容到DEFAULT_CAPACITY(也就是10)
+                transient Object[] elementData;
 
+                elementData=DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
+                只要增加了一个元素,就变成了:
+                elementData=new Object[DEFAULT_CAPACITY]
+                ArrayList有一个属性,是元素的个数,不是数组长度。
+                而是数组中存储有效元素的个数。
+                private int size;
+                ArrayList中有一个返回元素个数的方法:size(),返回的就是size属性。
+                判断是否为空isEmpty()返回的就是size是否等于0
 
-
+                ArrayList有三个构造方法:
+                    ArrayList(int initialCapacity)  创建一个ArrayList集合对象,指定初始容量为initialCapacity
+                    ArrayList() 创建一个ArrayList集合对象,指定初始容量为0:
+                        elementData=DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
+                        把维护的elementData数组,设置为空数组。
+                    ArrayList(Collection<? extends E> c)    创建一个ArrayList集合对象,传入的是Collection接口的实现类对象。
+                    其实就是把另一个集合对象的元素加入到新建的ArrayList结合对象中
 
      */
+    public static void main(String[] args) {
+        ArrayList list01=new ArrayList<>(); //创建一个默认容量为10集合
+        ArrayList list02=new ArrayList<>(20);//创建一个初始容量为20集合
+        ArrayList list03=new ArrayList<>(list02);//创建一个集合,以另一个集合为参数,加入到当前集合。
+
+        System.out.println(list01.size());
+        System.out.println(list02.size());
+        System.out.println(list03.size());
+    }
+
+
 
 }

+ 79 - 0
课堂笔记/01-JavaSE基础-笔记/20260729-笔记.md

@@ -239,6 +239,79 @@ Vector     LinkedHashSet
 
 > 📄 来源:`collection/Demo02.java`
 
+### 2.4 ArrayList 底层实现详解
+
+`ArrayList` 是 `List` 接口最常用的实现类,底层使用**可变数组**(动态数组)存储数据。
+
+#### 2.4.1 核心特性
+
+- **本质**:长度可变的数组,底层维护的是一个 `Object[] elementData`
+- **允许存储 `null`**
+- 和 `Vector` 类似,但**不是线程同步的**(非线程安全),性能更高
+- 内部维护一个 `size` 属性,表示数组中**有效元素的个数**(不是数组长度)
+- `size()` 方法返回 `size` 属性
+- `isEmpty()` 返回 `size == 0`
+
+> 📄 来源:`collection/Demo02.java`
+
+#### 2.4.2 默认容量与扩容机制
+
+```java
+// 默认初始容量为 10
+private static final int DEFAULT_CAPACITY = 10;
+
+// 空数组(用户指定容量为 0 时使用)
+private static final Object[] EMPTY_ELEMENTDATA = {};
+
+// 默认容量空数组(无参构造时使用)
+private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
+
+// 底层维护的数组
+transient Object[] elementData;
+```
+
+**扩容流程:**
+1. 使用无参构造时,`elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA`(容量为 0 的空数组)
+2. 第一次添加元素时,立即将容量**扩容到 `DEFAULT_CAPACITY`(10)**
+3. 后续元素超出容量时,自动按 **1.5 倍** 扩容(`oldCapacity + (oldCapacity >> 1)`)
+
+#### 2.4.3 三个构造方法
+
+| 构造方法 | 说明 |
+|----------|------|
+| `ArrayList()` | 无参构造,`elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA`(初始容量 0,首次添加时扩容到 10) |
+| `ArrayList(int initialCapacity)` | 指定初始容量,若大于 0 则 `elementData = new Object[initialCapacity]`;若为 0 则 `elementData = EMPTY_ELEMENTDATA` |
+| `ArrayList(Collection<? extends E> c)` | 传入另一个集合对象,将其所有元素添加到新建的 `ArrayList` 中 |
+
+```java
+// 无参构造 — 默认容量 10(懒加载,首次 add 时扩容)
+ArrayList list01 = new ArrayList<>();
+
+// 指定初始容量为 20
+ArrayList list02 = new ArrayList<>(20);
+
+// 以另一个集合为参数创建
+ArrayList list03 = new ArrayList<>(list02);
+
+System.out.println(list01.size()); // 0
+System.out.println(list02.size()); // 0
+System.out.println(list03.size()); // 0
+```
+
+> 📄 来源:`collection/Demo02.java`
+
+#### 2.4.4 关键属性速查
+
+| 属性/方法 | 说明 |
+|-----------|------|
+| `DEFAULT_CAPACITY = 10` | 默认初始容量 |
+| `elementData` | 底层维护的 `Object[]` 数组 |
+| `size` | 有效元素的个数(非数组长度) |
+| `size()` | 返回 `size` 属性 |
+| `isEmpty()` | 返回 `size == 0` |
+
+> 💡 **注意**:`ArrayList` 的 `size` 是元素个数,`elementData.length` 才是数组的物理容量(`capacity`),二者不一定相等。`size <= capacity` 恒成立。
+
 ---
 
 ## 三、随堂练习要点
@@ -252,6 +325,7 @@ Vector     LinkedHashSet
 | 包装类缓存机制 | -128~127 缓存池,`==` vs `equals()` | — |
 | 集合框架概述 | 集合 vs 数组对比,体系结构 | `collection/Demo01.java` |
 | 线性表数据结构 | 栈/队列/数组/链表 特点 | `collection/Demo02.java` |
+| **ArrayList 底层原理** | **可变数组、默认容量10、扩容机制、三个构造方法、size vs capacity** | `collection/Demo02.java` |
 
 ### 包装类重点
 
@@ -269,6 +343,11 @@ Vector     LinkedHashSet
 2. **记忆体系结构**:Collection(List / Set)和 Map 两大分支
 3. **掌握四种线性表结构**:栈(LIFO)、队列(FIFO)、数组(查询快增删慢)、链表(增删快查询慢)
 4. **关联实现类**:`ArrayList` → 数组,`LinkedList` → 链表/队列/栈
+5. **ArrayList 底层细节**:
+   - 默认容量 10(懒加载,首次 `add` 才扩容)
+   - 三个构造方法的区别
+   - `size` 与 `capacity` 的区别:`size` 是元素个数,`capacity` 是数组物理长度
+   - 允许存储 `null`,非线程安全
 
 ---