hashmap是map这种数据结构的一种实现方式,本身数据存储无序,检索操作的时间复杂度是常量级别,效率非常高。
hashmap的底层是一个数组,数据存储在数组的不同位置。
我们知道数组本身是线性结构,如果按照值去检索数据需要一个个去遍历,时间复杂度是O(n)级别,效率并不高。但是数组还可以按照索引去检索,因为数组在内存里是连续的,知道了具体的索引,很快就能算出来内存地址,实现随机读取的效果,不需要一个个去遍历。
hashmap就是利用了数组索引查找的特点才能有如此高的检索效率的
把key映射到具体的索引值也很简单,hashmap计算key的hash值,它是一个int数字,对这个数字和数组个数取模就能映射到具体的索引值了
hashmap中数组的长度总是大于数据的长度的,目的就是为了能让不同的key映射到不同的索引值。
理想状态是key映射到索引值不会重复,但是在实际操作过程中这个很难实现,于是有了hash冲突的问题。
对于hash冲突,hashmap的解决方式链式地址法,数组的每个索引可能存放不知一个数据,如果多个key映射到同一个地址,那这些数据组成一个链表存储在数组的这个位置。
我们知道链表这种数据结构的检索效率其实是不高的,当链表长度过长以后,检索效率大大下降,于是jdk1.8优化这部分结构,当链表长度超过8个后使用红黑树来替换链表
所以很多人说hashmap的底层结构是数组+链表+红黑树。但是我更想说它就是一个数组,因为引入链表和红黑树是它的无奈之举。数组才是hashmap的灵魂,hashmap希望自己只是一个数组。