本帖最后由 Jim-剣◆﹏ 于 2013-11-30 00:22 编辑
今早回复一帖子,发现一问题
我先说说我对hashSet对去除重复元素的看法,如有不对,大伙给我指出来
hashSet集合添加重复对象的识别方法是:
首先根据对象的hashCode值进行比较
如果hashCode值不同,则认为是不同的对象,直接添加进hashSet集合中
如果hashCode值相同,则继续用对象的equals方法比较,结果返回true则认为对象相同,添加失败,返回false则认为对象不同,添加成功
如果添加的对象没有覆写hashCode方法,那么此时的对象则是继承Object类的hashCode方法(经过查阅百度和API文档,得知Object中的hashCode方法是一个抽象方法,但是最终的实现是更具对象的内存地址值转化成一个int类型的值),hashCode值可以直观看成是对象内存地址值
如果添加的对象没有覆写equals方法,那么此时对象也是继承Object类的equals方法,进查阅API和源码,Object类中的equals方法内部实现是通过“=”比较两个对象的内存地址来实现的。
- import java.util.*;
- class ReflectPoint {
- private int x;
- private int y;
- ReflectPoint(int x, int y) {
- this.x = x;
- this.y = y;
- }
- @Override
- public boolean equals(Object obj) {
- System.out.println("hashCode一致,调用equals");
- return false;
-
- }
- class CollectionDemo {
- public static void main(String[] args) {
- myTestFunc();
- }
- static void myTestFunc() {
- Collection collections = new HashSet();
- ReflectPoint pt1 = new ReflectPoint(3, 3);
- ReflectPoint pt2 = new ReflectPoint(5, 5);
- ReflectPoint pt3 = new ReflectPoint(3, 3);
- ReflectPoint pt4 = pt1;
- System.out.println(collections.add(pt1));
- System.out.println(collections.add(pt2));
- System.out.println(collections.add(pt3));
-
- System.out.println(collections.add(pt1));
- System.out.println(collections.add(pt4));
-
- System.out.println(collections.size());
- }
- }
复制代码
的对象覆写了equals,并且无论对象内容是否相同,固定返回false值
期待的结果应该是
添加:true
添加:true
添加:true
添加:true
添加:true
元素个数:5
但是运行结果为
添加:true
添加:true
添加:true
添加:false
添加:false
元素个数:3
也就是说,pt1和pt4不能被重复添加,
问题一:为什么呢?进行添加操作的时候,会检查对象的hashCode值和equals,pt4和pt1的hashCode值固然相等(输出pt4和pt1的hashCode值验证过),继而就应该执行equals(),而且equals必定返回false,所以,应该认为pt1和pt4是不同的对象,成功添加,这里为什么添加失败?
问题二::没有执行equals,因为没有执行输出语句System.out.println("hashCode一致,调用equals"),两对象的hashCode值一致,为啥不执行equals?以下修改并覆写hashCode方法
- class ReflectPoint {
- private int x;
- private int y;
- ReflectPoint(int x, int y) {
- this.x = x;
- this.y = y;
- }
- @Override
- public boolean equals(Object obj) {
- System.out.println("hashCode一致,调用equals");
- return false;
- }
- @Override
- public int hashCode() {
- // TODO Auto-generated method stub
- return (this.x + this.y) * 31;
- }
- }
复制代码
此时打印的结果为:
添加:true
添加:true
hashCode一致,调用equals
添加:true
hashCode一致,调用equals
添加:false
hashCode一致,调用equals
添加:false
元素个数:3
明显这次在hashCode值相同的情况下,程序调用了对象的equals方法
问题三:对象仍然添加失败,这是为何?
|