|
|
@@ -1,4 +1,4 @@
|
|
|
-# 20260731 课堂笔记 — LinkedList 多接口形态 / Iterator 迭代器
|
|
|
+# 20260731 课堂笔记 — LinkedList 多接口形态 / Iterator 迭代器 / Map集合入门
|
|
|
|
|
|
- **日期**:2026-07-31
|
|
|
- **项目**:`c260731`
|
|
|
@@ -12,8 +12,9 @@
|
|
|
1. [LinkedList 多接口形态(List / Queue / Deque)](#1-linkedlist-多接口形态list--queue--deque)
|
|
|
2. [Iterator 迭代器](#2-iterator-迭代器)
|
|
|
3. [Collection 体系回顾:Iterable → Collection](#3-collection-体系回顾iterable--collection)
|
|
|
-4. [随堂练习要点](#4-随堂练习要点)
|
|
|
-5. [拓展阅读](#5-拓展阅读)
|
|
|
+4. [Map 集合(双列集合)与 HashMap 入门](#4-map-集合双列集合与-hashmap-入门)
|
|
|
+5. [随堂练习要点](#5-随堂练习要点)
|
|
|
+6. [拓展阅读](#6-拓展阅读)
|
|
|
|
|
|
---
|
|
|
|
|
|
@@ -168,9 +169,10 @@ while (it.hasNext()) { // 2. 判断是否有下一个
|
|
|
### 继承结构
|
|
|
|
|
|
```
|
|
|
-Iterable<E> —— 根接口,定义了 iterator()
|
|
|
- │
|
|
|
-Collection<E> —— 单列集合根接口(继承 Iterable)
|
|
|
+单列集合(Collection 体系) 双列集合(Map 体系)
|
|
|
+Iterable<E> ───────────── Map<K,V> 接口(键值对)
|
|
|
+ │ │
|
|
|
+Collection<E> ── 并行存在 ──> HashMap<K,V>(最常用实现类)
|
|
|
├── List<E> —— 列表:有序、可重复、带索引
|
|
|
│ ├── ArrayList<E> —— 数组结构,随机访问快
|
|
|
│ └── LinkedList<E> —— 双链表结构,插入删除快
|
|
|
@@ -208,7 +210,86 @@ Deque<Object> deque = new LinkedList<>();
|
|
|
|
|
|
---
|
|
|
|
|
|
-## 4. 随堂练习要点
|
|
|
+## 4. Map 集合(双列集合)与 HashMap 入门
|
|
|
+
|
|
|
+### 概念
|
|
|
+
|
|
|
+`Map` 集合是一个**接口**,属于**双列集合**,与单列集合(Collection)并行存在:
|
|
|
+
|
|
|
+```java
|
|
|
+public interface Map<K, V>
|
|
|
+```
|
|
|
+
|
|
|
+- 泛型有两个:`K` 代表 **Key(键)** 的类型,`V` 代表 **Value(值)** 的类型
|
|
|
+- 存储的基本单位是**键值对**(`<Key, Value>`)
|
|
|
+- **键(Key)不可以重复,值(Value)可以重复**
|
|
|
+- 简单理解:可以把 Map 的键(Key)理解成数组中的**索引**,只是这个索引是我们自己定义的;Map 的值(Value)可以理解成数组的**元素**,元素可以重复,元素之间的顺序根据索引(Key)来确定
|
|
|
+- Map 中最常用的实现类是 **`HashMap`**
|
|
|
+
|
|
|
+创建 `HashMap` 对象有两种方式:
|
|
|
+
|
|
|
+```java
|
|
|
+Map<String,Object> map = new HashMap<>(); // 方式一:接口多态,左边声明为 Map 接口
|
|
|
+HashMap<String,Object> map1 = new HashMap<>(); // 方式二:直接用实现类
|
|
|
+```
|
|
|
+
|
|
|
+### Map 常用方法
|
|
|
+
|
|
|
+| 方法 | 说明 |
|
|
|
+|------|------|
|
|
|
+| `V put(K key, V value)` | 向 Map 集合中添加元素(键值对) |
|
|
|
+| `V get(Object key)` | 根据 Key 键获取 Value 值 |
|
|
|
+| `Set<K> keySet()` | 把当前 Map 集合中的所有 Key 组成一个 Set 集合(无序的单列集合) |
|
|
|
+| `Collection<V> values()` | 把所有的 Value 值组合成一个单列集合 |
|
|
|
+| `Set<Map.Entry<K,V>> entrySet()` | 返回一个单列 Set 集合,集合中每个元素都是一个 Map 的内部类(Entry)对象,即由 Map 的键值对组成的一个类型 |
|
|
|
+
|
|
|
+### 代码示例
|
|
|
+
|
|
|
+```java
|
|
|
+// 来源:course/Demo03.java
|
|
|
+package course;
|
|
|
+
|
|
|
+import java.util.Collection;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
+
|
|
|
+public class Demo03 {
|
|
|
+ public static void main(String[] args) {
|
|
|
+ Map<String,Object> map = new HashMap<>();
|
|
|
+ map.put("id","x1001");
|
|
|
+ map.put("name","张三");
|
|
|
+ map.put("age",25);
|
|
|
+ map.put("gender","男");
|
|
|
+
|
|
|
+ Collection<Object> values = map.values(); // 获取所有值
|
|
|
+ System.out.println(values); // [男, 张三, x1001, 25](无序,顺序≠添加顺序)
|
|
|
+ Set<String> set = map.keySet(); // 获取所有键
|
|
|
+ System.out.println(set); // [gender, name, id, age]
|
|
|
+
|
|
|
+ HashMap<String,Object> map1 = new HashMap<>();
|
|
|
+ map1.put("x001","张三");
|
|
|
+ map1.put("x002","李四");
|
|
|
+ map1.put("x003","王五");
|
|
|
+ map1.put("x004","赵六");
|
|
|
+
|
|
|
+ System.out.println(map1.values()); // [李四, 王五, 赵六, 张三]
|
|
|
+ System.out.println(map1.keySet()); // [x004, x003, x002, x001]
|
|
|
+ System.out.println(map1); // 直接打印:{x004=赵六, x003=王五, x002=李四, x001=张三}
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 关键理解
|
|
|
+
|
|
|
+1. **HashMap 无序**:从输出可以看到,键值对的**存储顺序与添加顺序不一致**——HashMap 底层根据键的哈希值(hashCode)决定存储位置。
|
|
|
+2. **键不可重复,值可重复**:同一个 Key 再次 `put` 会覆盖旧值;不同 Key 可以对应相同 Value。
|
|
|
+3. **Map 与 Collection 的关系**:二者并行——Collection 是**单列集合**(存单个元素),Map 是**双列集合**(存键值对)。
|
|
|
+4. **keySet() / values() 的用途**:Map 本身没有索引,想遍历键或值,就先转成单列集合(Set / Collection),再用迭代器或增强 for 遍历。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 5. 随堂练习要点
|
|
|
|
|
|
### 练习一:LinkedList 多接口引用
|
|
|
|
|
|
@@ -234,9 +315,22 @@ Deque<Object> deque = new LinkedList<>();
|
|
|
2. 为什么 LinkedList 用 `for + get(i)` 效率低?—— 每次 `get(i)` 都要从头遍历节点,时间复杂度 O(n),而迭代器沿链表逐个移动只需 O(1)
|
|
|
3. 增强 for 的底层机制是什么?—— 编译器会把 foreach 翻译成迭代器遍历
|
|
|
|
|
|
+### 练习三:Map 集合键值对操作
|
|
|
+
|
|
|
+**核心步骤**:
|
|
|
+1. 创建一个 `HashMap<String,Object>`,用 `put()` 添加一组学生信息(`id` / `name` / `age` / `gender`)
|
|
|
+2. 用 `keySet()` 获取所有键(返回 `Set<String>`)
|
|
|
+3. 用 `values()` 获取所有值(返回 `Collection<Object>`)
|
|
|
+4. 直接打印 `map` 观察 HashMap 的无序特性
|
|
|
+
|
|
|
+**思考**:
|
|
|
+1. Map 与 Collection 有什么区别?—— Collection 是单列集合(存单个元素),Map 是双列集合(存键值对)
|
|
|
+2. 为什么 HashMap 打印时顺序和添加顺序不一致?—— 底层根据键的 hashCode 哈希决定存储位置
|
|
|
+3. 为什么 `keySet()` 返回 Set?—— 键不可重复,正好符合 Set 的不可重复特性
|
|
|
+
|
|
|
---
|
|
|
|
|
|
-## 5. 拓展阅读
|
|
|
+## 6. 拓展阅读
|
|
|
|
|
|
### 官方文档
|
|
|
|
|
|
@@ -245,10 +339,12 @@ Deque<Object> deque = new LinkedList<>();
|
|
|
- [LinkedList (JDK 17)](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/LinkedList.html)
|
|
|
- [Queue (JDK 17)](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Queue.html)
|
|
|
- [Deque (JDK 17)](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Deque.html)
|
|
|
+- [Map 接口 (JDK 17)](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html)
|
|
|
+- [HashMap (JDK 17)](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/HashMap.html)
|
|
|
|
|
|
### 推荐阅读
|
|
|
|
|
|
-- 《Java 核心技术 卷 I》第 9 章 集合 —— 迭代器与 foreach 的关系
|
|
|
+- 《Java 核心技术 卷 I》第 9 章 集合 —— 迭代器与 foreach 的关系、Map 集合
|
|
|
- 《Effective Java》第 3 版 第 58 条:优先使用 foreach 循环而非传统 for 循环
|
|
|
|
|
|
### 相关知识点
|
|
|
@@ -258,3 +354,4 @@ Deque<Object> deque = new LinkedList<>();
|
|
|
| ArrayList 底层原理(0729) | LinkedList 多接口形态(List/Queue/Deque) | ListIterator(双向迭代) |
|
|
|
| LinkedList 双链表理论(0730) | Iterator 迭代器 | 增强 for / forEach 方法 |
|
|
|
| 泛型与集合体系(0729) | Iterable → Collection 继承体系 | Set 集合与 Map 迭代 |
|
|
|
+| Collection 单列集合体系 | Map 集合 / HashMap 入门 | Map 遍历(entrySet)、HashMap 底层哈希表 |
|