Java HashMap 底层原理
你平时用手机存联系人,是不是总喜欢把名字拼音首字母相同的放一起?比如“张三”“张四”都归到“Z”的文件夹里,找的时候直接翻“Z”文件夹就行,不用一个个翻所有名字。Java里的HashMap,其实就是现实中这种“归类存东西”的工具,咱们今天就用日常例子拆解它的底层逻辑。
最核心的“储物格”:数组
HashMap的底层第一块“地盘”是数组,就像手机里用来装不同首字母文件夹的“大抽屉”,每个格子都有自己的编号,这个编号叫“下标”,从0开始数。

比如你要存一个“手机号=138xxxx1234,姓名=张三”的信息,HashMap会先算“张三”拼音首字母“Z”对应的数字,然后找数组里编号对应的格子,把这个信息放进去。这个算数字的过程叫“哈希运算”,目的是快速找到该放哪个储物格。
避免重复的“隔层”:链表和红黑树
有时候会碰到两个信息算出来的编号一样,比如“张五”也算出“Z”对应的下标,这时候就不能直接塞进同一个格子,不然两个信息会挤在一起。这时候格子里会先拉一条“链子”,把同个编号的信息串起来,就像你把两个同名首字母的文件放进同一个“Z”文件夹里,用文件夹里的分隔条串好。
但如果同一个格子里的信息越来越多,找的时候得一个个翻,就会变慢。HashMap到了一个阈值(一般是8个),会自动把这条“链子”改成“红黑树”,红黑树就像按姓氏笔画排好的文件,找的时候能直接跳转到对应位置,不用逐个翻,速度一下子就提上来了。
自动扩容的“扩容机制”
数组的大小是有限的,你存的联系人越来越多,“Z”文件夹、“L”文件夹会越来越满,HashMap就得把数组变大。它的扩容规则很简单:当所有格子的信息总数超过数组容量的75%时,就会把数组扩大到原来的2倍,然后把之前存的所有信息重新算一遍下标,放到新数组的对应位置。
举个生活化的例子:你原来的抽屉只有10个格子,每个格子放7个文件,总共能放70个;现在你存到第71个文件了,抽屉不够用,就换成20个格子的新抽屉,把之前的70个文件重新归类放好,这样每个格子又不会太挤,找起来更快。
小总结
HashMap的底层逻辑其实就是这么简单:先用数组当基础储物格,用哈希运算快速定位;碰到同个格子的多个信息,先拉链表串起来,多了就转红黑树提速;信息太多就自动扩容,保证效率。平时咱们用它存键值对的时候,不用管这些底层细节,就像用手机存联系人不用知道系统怎么排序,但了解这些原理,碰到“为什么HashMap读得快”“为什么要转红黑树”这类问题,就能说清楚来龙去脉了。