在Java开发的日常工作中,集合就像我们的“万能工具箱”——存数据、取数据、筛数据都离不开它。而Map作为工具箱里的“键值对神器”,更是高频出镜!你是不是也曾对着HashMapTreeMapHashtable傻傻分不清?今天咱们就抛开枯燥的官方文档,用“家族八卦”的方式扒一扒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家族都不怕:

方法

作用

put(K key, V value)

新增/修改键值对(key存在则覆盖value)

remove(Object key)

根据key删除对应的键值对

V get(Object key)

根据key获取value(不存在返回null)

boolean containsKey(Object key)

判断是否包含指定key

int size()

获取键值对的个数

Set<K> keySet()

获取所有key的集合(遍历常用)

基础用法示例(入门必看)


三、Map家族核心成员:各有各的“人设”

1. HashMap:效率卷王(开发高频选手)

HashMap是Map家族的“顶流”,日常开发中80%的场景都用它,先搞懂它的核心逻辑:

底层原理(划重点!面试必问)
  • 底层结构:JDK1.8后是「数组 + 链表 + 红黑树」(之前是数组+链表)

  • 存储规则

    • 计算key的hashCode()值,通过 hashCode % 数组长度 确定存储位置;

    • 如果该位置为空,直接存;如果已有元素,先对比hashCode,再用equals()判断是否是同一个key:

      1. 是同一个key:覆盖value;

      2. 不是同一个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)

五、实战选型建议(避坑指南)

  1. 日常开发优先选HashMap(效率最高,满足90%场景);

  2. 要“插入有序”选LinkedHashMap(比如记录用户操作日志);

  3. 要“key排序”选TreeMap(比如按时间/ID排序展示数据);

  4. 多线程并发场景:别用Hashtable,选ConcurrentHashMap(JUC包下的高效并发Map);

  5. 禁止null键/值的场景:可考虑Hashtable,但更推荐手动校验+HashMap。

总结

  1. Map是Java双列集合的核心,以键值对存储,key唯一、value可重复,核心方法包括put/remove/get等;

  2. HashMap是基础款,效率最高但无序;LinkedHashMap是有序版HashMap;TreeMap是排序版Map;Hashtable是老派线程安全版(不推荐);

  3. 选型核心:看是否需要有序、是否需要排序、是否需要线程安全,按需选择即可。

最后想说:集合看似简单,但底层原理(比如HashMap的扩容、红黑树转换)是面试高频考点,日常用的时候多想想“为什么选这个”,而不是随手就new HashMap~

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐