本帖最后由 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方法 
问题三:对象仍然添加失败,这是为何? 
 
 |