老生常谈 HashMap 为什么要重写HashCode() 和equals()方法

HashMap 在jdk1,8采用 数组+链表+(红黑树)的方式实现。初始容量为16,负载因子0.75。HashMap存入键值对即Key和Value,键不允许重复,值允许重复,允许NULL键NULL值,且NULL键只能有一个。

HashMap首先调用HashCode()方法计算元素(Key)的哈希值,系统根据哈希值确定元素的存储位置,如果此位置有元素存在,则比较(使用equals方法)Key是否相同,相同则直接替换,不同则在下面形成链表。

Object类是所有类的父类,Object类中的HashCode()方法是没有被重写过的。此时HashCode()方法返回的是对象的地址值,两个不同的对象调用HashCode()方法当然返回不同的地址值,此时若是向HashMap中存入两个键值对  (a,3)(a,3) 注意:这是两个不同对象,如果不重写HashCode()方法,则这两个对象都会被存进Hashmap,而它们的键确实相同的,这就矛盾了。

equals()方法只能比较引用型数据,不能用于基本类型数据比较。在Object类中equals()方法同样没有被重写,比较的是对象的地址值。HashMap里的数组是有初始容量的,系统根据哈希值确定元素的存储位置(采用了某种算法),有可能出现以下情况数组中某个位置已经存入了(a,3)键值对,这时另一个对象(a,3)想存入HashMap,其哈希值与存入的(a,3)肯定不同,但是HashMap数组长度有限,系统根据哈希值计算正好也要把这个(a,3)存到已经存入的(a,3)位置,如果没有重写equal()方法,则这时比较的是两个对象的地址值,因为是不同对象,地址值肯定不同,那么这个(a,3)就会在已经存入的(a,3)下形成链表存进去,那么此时也就矛盾了。

上一篇:JAVA基础学习


下一篇:【Java基础学习笔记】12、常用类Object