为什么重写Equals方法的时候必须同时重写HashCode方法?
一个对象的初始状态,在Equals方法和HashCode方法都没有重写之前,两个对象调用这两个方法进行比较的时候,比较的都是对象的地址,只有两个对象的地址相同Equals方法才会返回true,HashCode方法也才会返回true;
当你重写Equals方法的时候,为什么一定要重新HashCode方法呢?如果不重写HashCode方法会有什么不妥呢?
假如我们现在往一个hashmap集合存键值对,我们知道hashmap内部使用的结构是 散列表+链表+红黑树的形式,首先会根据对象的HashCode值计算出键值对对应的散列表的索引,那假如两个对象的hashCode值不同,存放一个键值对之后,计算的另外一个键值对对应的散列表索引就和第一个不一样,这样就会直接的把数据存储到散列表对应数组的地方,这两个对象会被当成是两个不同的对象。
但是问题是,假如此时对象重写了equals方法,把原来的比较地址换成了比较内容,那么两个不同地址的对象它的比较结果就可能相同。但是问题是此时hashcode方法并没有重写,因此它比较的还是地址,所以一个不同于上一个对象的地址就会被存储到散列表的不同索引的地方,当成是一个不同的对象。但是其实这两个对象的equals方法的比较结果是相同的,因为此时并不是比较的对象地址而是比较的内容。
因此这就会出现一个问题,我们存放到hashmap中的键值对的key,可能会存在多个相同的key,这就会出现问题了,因为一个hashmap集合中要求key必须不重复。
因此当重写equals方法的时候也必须重写hashcode方法,二者如果比较对象地址都必须比较地址,比较对象内容必须都比较对象内容。