Set集合为何必须要重写类中的HashCode和equals方法?
1.问题
我们知道Set集合必须要重写HashCode和equals方法,原因是什么呢?
2.解决
最重要的原因是Set集合有不包含重复元素的特性!!!
这个重复元素由谁来定义他是否重复呢?就是由类中的HashCode和equals方法,
先由HashCode判断,但是存在Hash冲突情况,一个桶可能有多个,所以再使用equals方法进行一次比较即可!
参考:[使用Set集合为何要重写hashcode()与equals()方法(https://blog.csdn.net/Wangtuoshi/article/details/101560283)
使用Set集合为何要重写hashcode()与equals()方法
首先,set集合的特点是无序、元素唯一、允许元素值为null,但只能有一个null元素。
equals()和hashcode()是object中的方法,所以每个类中都有这两个方法,但在实际应用中往往需要重写这两个方法。
hashcode()与equals()方法的调用机制
hashCode方法可以这样理解:它返回的就是根据对象的内存地址换算出的一个值。这样一来,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了,即有相同的哈希值,就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。
一个例子
假设场景:java中的Set集合的特性之一是会去除相同的元素。假设在Set集合中存狗对象,同一只狗只能在Set集合中存一次,判断一只狗是否是同一只狗的依据为:品种相同,名字相同,年龄相同,即为同一只狗。
编写实体类,并未重写两个方法
编写测试类
输出结果
显然,结果中出现两只哈士奇,应该判断为一只狗。出现这个结果是因为new出的每一个对象,哈希值是不同的
重写hashcode()方法
输出结果
重写hashcode()方法后,现在两只哈士奇的哈希值是相同的,进而执行equals()方法,但由于没有重写equals,默认使用"=="来判断,即比较两只哈士奇在内存中的地址,返回的必然为false,故依然不能去重。
重写equals方法
输出结果
这样set集合的去重就实现了。
总结
1.若两个对象hashCode返回相同值,则equals不一定返回true。
2.若两个对象hashCode返回不同值,则equals一定返回false。
3.要想保证元素的唯一性,必须同时重写hashCode和equals才行。