Java两个对象的HashCode相等但这两个对象不一定相同------hash算法
hash算法是一种思想,例如最简单的哈希函数:求余运算。
例如有不同的整数通过对指定数(如2)的求余运算得到余数就那么几个。不同的整数可可以得到相同的余数即hash值
HashCode就是将对象的内存地址转化为整数后进行hash运算后得到的hash值。
所以两个对象的HashCode相同但内存地址不一定相同。
HashMap的底层也是这样实现的。数组加链表(如下图),当我们往HashMap中put元素的时候,先根据key的hashCode重新计算hash值,根据hash值得到这个元素在数组中的位置(即下标),如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置上。
HashMap中解决碰撞的方法
根据key的hashcode得到存储位置bucket(桶),有可能不同的key得到的位置一样这样就出现了hash碰撞。这样就引入了每一个bucket中的一个链表结构来解决碰撞,hashMap如果发生hash碰撞则将键值对象存在链表的下一个节点。
hashMap底层数据结构到底是怎样的
hashMap包含一个bucket数组和每一个bucket对应的链表结构,每一个K-V对象存放在这个链表中,这个链表结构主要用来解决hash碰撞后键值对象存储问题。
equals()和hashCode()的应用,以及它们在HashMap中的重要性
当两个不同的键对象的hashcode一样,他们会存储在同一个bucket位置的链表中,通过遍历这个链表再根据键对象的equals方法用来找到存放在链表中的键值对(Entry)对象。get方法用到equals和hashcode方法,put则用到hashcode方法。
不可变对象的好处
用不可变对象作为key,是非常合适的。
1)如果存放时key对象的hashcode和获取时这个key对象的hashcode不一致时则无法获取值对象。
2)不可变对象是线程安全的,减少碰撞的几率。
https://mp.weixin.qq.com/s?src=11×tamp=1604618063&ver=2689&signature=dgJV3qTFiCFx-CU-MEFROLZaDta89k8jz1rILMrc2NCXicDcE2GoyJYrbIDH6JUFf-CzBxC7CF1UelrgqJZMlBarSAB0fOSdhLeBIiQVP0ty9kZ402PnRJCv3HLGy7&new=1