【Java集合】Map家族大揭秘!HashMap/TreeMap/Hashtable谁才是职场卷王?
在Java开发的日常工作中,集合就像我们的“万能工具箱”——存数据、取数据、筛数据都离不开它。而Map作为工具箱里的“键值对神器”,更是高频出镜!你是不是也曾对着HashMap、TreeMap、Hashtable傻傻分不清?今天咱们就抛开枯燥的官方文档,用“家族八卦”的方式扒一扒Map家族的那些事儿,顺便把集合体系、核心用法、底层原理一次性讲透~
一、先搭框架:Java集合的“两大阵营”
聊Map之前,先快速过一遍Java集合的整体体系,避免大家“只见树木不见森林”:
1. 单列集合:Collection接口(独行侠)
Collection是所有单列集合的顶级接口(只存单个元素),核心分支是:
-
List接口(有序、可重复):像排队买奶茶,位置固定、能加塞
-
ArrayList:动态数组“效率怪”,查改快、增删慢
-
Vector:ArrayList的“老大哥”(JDK1.0),线程安全但效率拉胯
-
LinkedList:双向链表“灵活派”,增删快、查改慢
-
-
Set接口(无序、不可重复):像摇号中奖,中了就是中了,不能重复
-
HashSet:底层数组+链表,查重快
-
LinkedHashSet:有序版HashSet,数组+双向链表
-
TreeSet:红黑树“整理控”,自动排序
-
2. 双列集合:Map接口(情侣档)
Map是所有双列集合的顶级接口,以键值对(Key-Value)形式存储数据——Key是“唯一标识”(不能重复),Value是“对应内容”(可重复),就像给每个数据贴了唯一标签,找的时候直接按标签搜,效率拉满!
二、Map接口:所有“键值对选手”的通用规则
不管是HashMap还是TreeMap,都得遵守Map接口的“家规”,先掌握这些核心方法,走遍Map家族都不怕:
|
方法 |
作用 |
|
|
新增/修改键值对(key存在则覆盖value) |
|
|
根据key删除对应的键值对 |
|
|
根据key获取value(不存在返回null) |
|
|
判断是否包含指定key |
|
|
获取键值对的个数 |
|
|
获取所有key的集合(遍历常用) |
基础用法示例(入门必看)
三、Map家族核心成员:各有各的“人设”
1. HashMap:效率卷王(开发高频选手)
HashMap是Map家族的“顶流”,日常开发中80%的场景都用它,先搞懂它的核心逻辑:
底层原理(划重点!面试必问)
-
底层结构:JDK1.8后是「数组 + 链表 + 红黑树」(之前是数组+链表)
-
存储规则:
-
计算key的
hashCode()值,通过hashCode % 数组长度确定存储位置; -
如果该位置为空,直接存;如果已有元素,先对比
hashCode,再用equals()判断是否是同一个key:-
是同一个key:覆盖value;
-
不是同一个key:挂到链表末尾;
-
-
-
扩容机制:
-
初始数组长度是16,负载因子(使用率阈值)0.75;
-
当元素个数 > 16*0.75=12 时,数组扩容2倍(变成32);
-
当链表长度 > 8 且 数组长度 > 64 时,链表自动转为红黑树(提升查询效率)。
-
核心特点
-
非线程安全(多线程用会出问题);
-
允许null键、null值(key只能有一个null,value可以多个);
-
无序(存储顺序≠插入顺序);
-
查询/新增效率极高(平均O(1))。
2. LinkedHashMap:有强迫症的“有序卷王”
LinkedHashMap是HashMap的“亲弟弟”,完全继承HashMap的特性,只多了一个“强迫症”——保留元素的插入顺序。
底层原理
在HashMap的“数组+链表”基础上,额外加了一条双向链表,专门记录元素的插入顺序,遍历的时候按这个链表走,就能保证有序。
代码示例(对比HashMap的无序)
3. TreeMap:爱排序的“整理控”
TreeMap是Map家族里的“整理达人”,底层基于红黑树实现,核心特点是自动对key排序(默认升序,也可自定义比较规则)。
核心特点
-
非线程安全;
-
不允许null键(会抛空指针),允许null值;
-
有序(按key自然排序,比如字符串按字母、数字按大小);
-
适合需要对key排序的场景(比如按用户ID升序展示)。
代码示例(自动排序)
4. Hashtable:老派“安全控”
Hashtable是Map家族的“老大哥”(JDK1.0就出道),是HashMap的“线程安全版”,但现在基本被淘汰了。
核心特点
-
线程安全(方法加了
synchronized),但效率极低; -
不允许null键、null值(会抛空指针);
-
底层是数组+链表(没有红黑树优化);
-
注意:并发场景优先用
ConcurrentHashMap(比Hashtable高效),而非Hashtable。
四、Map家族成员对比(一张表搞定)
|
类名 |
线程安全 |
允许null键/值 |
有序性 |
底层结构 |
适用场景 |
|
HashMap |
❌ |
✅(key仅1个null) |
无序 |
数组+链表+红黑树 |
绝大多数日常场景(追求效率) |
|
LinkedHashMap |
❌ |
✅ |
插入顺序 |
数组+双向链表+红黑树 |
需要保留插入顺序的场景 |
|
TreeMap |
❌ |
❌(key)/✅(value) |
按key排序 |
红黑树 |
需要对key排序的场景 |
|
Hashtable |
✅ |
❌ |
无序 |
数组+链表 |
几乎不用(并发用ConcurrentHashMap) |
五、实战选型建议(避坑指南)
-
日常开发优先选HashMap(效率最高,满足90%场景);
-
要“插入有序”选LinkedHashMap(比如记录用户操作日志);
-
要“key排序”选TreeMap(比如按时间/ID排序展示数据);
-
多线程并发场景:别用Hashtable,选
ConcurrentHashMap(JUC包下的高效并发Map); -
禁止null键/值的场景:可考虑Hashtable,但更推荐手动校验+HashMap。
总结
-
Map是Java双列集合的核心,以键值对存储,key唯一、value可重复,核心方法包括put/remove/get等;
-
HashMap是基础款,效率最高但无序;LinkedHashMap是有序版HashMap;TreeMap是排序版Map;Hashtable是老派线程安全版(不推荐);
-
选型核心:看是否需要有序、是否需要排序、是否需要线程安全,按需选择即可。
最后想说:集合看似简单,但底层原理(比如HashMap的扩容、红黑树转换)是面试高频考点,日常用的时候多想想“为什么选这个”,而不是随手就new HashMap~
更多推荐




所有评论(0)