JavaSE9️⃣集合 - Map 体系
Map 接口
Map:存储 K-V 键值对(也称记录)。
无序,无下标,Key 唯一
Hashtable 类 | HashMap 类 | TreeMap 类 | |
---|---|---|---|
Java 版本 | 1.0 | 1.2 | 1.2 |
存储结构 | 数组+链表 | 数组+链表、红黑树 | 红黑树 |
线程安全 | ✔ | ❌ | ❌ |
说明 | K/V 非空 | K 和 V 可空 | 对集合元素自动排序(需实现 Comparable 接口) |
1、Hashtable
简单了解即可
1.1、成员结构
1.1.1、Entry<K, V>
Hashtable
的私有静态内部类。
-
哈希值
-
关键码值、元素值
-
后继结点
private static class Entry<K,V> implements Map.Entry<K,V> { final int hash; final K key; V value; Entry<K,V> next; ... }
1.1.2、成员变量
重要的成员变量(均由
private
修饰)
数据类型 | 说明 | 取值 | |
---|---|---|---|
table |
Entry<?, ?>[] | 哈希表 | - |
threshold |
int | 当存储元素个数超过该阈值时进行扩容 | 扩容阈值 = 容量 * 加载因子 |
loadFactor |
float | 加载因子 | 默认 0.75f |
keySet | Set<K> | 包含所有 key 的集合 | - |
values | Collection<V> | 包含所有 value 的集合 | - |
entrySet | Set<Map.Entry<K,V>> | 包含所有 key-value 的集合 | - |
1.1.3、构造方法
-
指定初始容量、加载因子
-
指定初始容量:默认加载因子
0.75f
-
无参构造:默认初始化容量
11
,默认加载因子0.75f
(此时扩容阈值8
)。public Hashtable(int initialCapacity, float loadFactor) { ... } public Hashtable(int initialCapacity) { this(initialCapacity, 0.75f); } public Hashtable() { this(11, 0.75f); }
1.2、Properties 类
Hashtable 子类,表示一组持久的属性。
-
Key
和Value
是 String 类型。 -
常用于保存和读取配置文件。
class Properties extends Hashtable<Object,Object> { public synchronized Object setProperty(String key, String value) { return put(key, value); } }
2、HashMap
篇幅有限,移步以下 2 篇博客。
- 哈希:
- 哈希表
- 哈希冲突
- 哈希在 Java 中的实现:
- 存储结构:数组 + 位桶(bucket)
- 哈希冲突:链地址法
- 检索机制
- 重写
equals()
和hashCode()
- 底层结构:
- 数据结构:数组 + 位桶 (Java 1.8+ 红黑树)
- 版本区别
- 成员结构:
- 位桶:Node<K, V>
- 成员变量:
- 默认初始容量:16
- 默认加载因子:0.75f
- 扩容阈值 = 容量 * 加载因子
- 树化阈值:8
- 退化阈值:6
- 最小树化容量:64
- 构造方法:
- 初始容量、加载因子
- 初始容量
- 无参
- Map
- 确定存储位置:
- 扰动函数 hash()
- 计算下标 indexfor()
- 操作:
- 添加元素 put()
- 扩容 resize()
- 查询 get()
- 删除 remove()
- 迭代器
- 对比 Hashtable
3、TreeMap
3.1、存储结构
红黑树
3.2、检索机制
基于
compareTo()
判断元素是否相等。
- 相等条件:
compareTo()
返回0
,无关 equals() 和 hashCode()。 - 使用方式:
- Comparable:对象实现 Comparable 接口。
- Comparator:创建 TreeSet 时,传入 Comparator 匿名内部类。
3.3、使用
3.3.1、Comparable 接口
对象实现 Comparable 接口,TreeMap 可直接存储对象。
-
对象:
public class Student implements Comparable<Student> { private String name; private int age; @Override public int compareTo(Student s) { // 规则:先比较姓名,再比较年龄 int c1 = this.name.compareTo(s.getName()); int c2 = this.score - s.getScore(); return c1 != 0 ? c1 : c2; } }
-
使用集合:
TreeSet<Student> set = new TreeSet<>; // 使用
3.3.2、Comparator
创建 TreeSet 时声明 Comparator 匿名内部类。
-
对象:
public class Student { private String name; private int age; }
-
使用集合:
// 一般形式 TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { int c1 = s1.getName().compareTo(s2.getName()); int c2 = s1.getScore() - s2.getScore(); return c1 != 0 ? c1 : c2; } }); // lambda表达式 TreeSet<Student> set = new TreeSet<>((s1, s2) -> { int c1 = s1.getName().compareTo(s2.getName()); int c2 = s1.getScore() - s2.getScore(); return c1 != 0 ? c1 : c2; });
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律