算法|如果你这么去理解HashMap就会发现它真的很简单( 二 )


但是又来了一个问题 , 通过上面的实验我们拿到的hashCode值很大 , 无法作为数组的下标 , 否则我们的数组占用的内存就太大了!
所以就采用了根据hashCode取余的方式 , 比如Java中的HashMap默认size是16 , 那么92599395%16=3 , 那么实际上abcde这个字符串就存储在HashMap数组中下标为3的地方 。
Hash冲突
上面已经讲过Hash算法无法做到完全均匀分布 , 也就是说可能会有那么两个不一样的字符串经过hash计算后得到相同的值 , 此时两个不同的字符串都得对应同一个数组下标上 , 这就造成了所谓的Hash冲突 。
因此 , 为了解决Hash冲突问题 , 我们需要下标对应的元素不再仅仅是当前对应的字符串了 , 而应该是当前的字符串再加上它的next节点的对象地址 , 这样的一个对象应该如下:
当根据key去找值时候 , 先计算出key的hash值再取余得到数组的下标 , 然后根据下标获取到元素 , 再判断该元素的key是否和当前的key相等(如何判断相等?equals方法!) , 如果不相等 , 继续取next节点 , 继续判断 。
说到这里大家如果对HashMap熟悉的话 , 是不是发现这其实就是HashMap的简单版 , 一个数组+链表的实现:
再看HashMap源码
如果你已经看到这里 , 那么我相信你一定已经了解了HashMap的结构了 , 那么请回去看HashMap的源码吧 , 你会发现原来是这么简单!这个时候你已经达到了“看山不是山”的境界了!面试官问你任何关于HashMap的问题相信你都能回答了 。
搞清楚了HashMap之后 , HashTable和HashMap的区别?ConcurrentHashMap是线程安全的基于分段锁的HashMap?为了优化链表的性能 , 当链表的数超过8之后就变成平衡树了等等 。。。
后面做的事情要么是为了线程安全要么就是为了性能 。
【算法|如果你这么去理解HashMap就会发现它真的很简单】如果本文对你有所帮助 , 欢迎点赞转发 , 也欢迎大家说说自己在学习HashMap时候自己的一些心得 , 方便大家一起学习共同成长!