重写equals 和hashCode 探解之洗洗脚(三)接下来看看重写equals 和hashCode 探解之洗洗脚(三)对于以下代码:
重写equals 和hashCode 探解之洗洗脚(三)
接下来看看重写equals 和hashCode 探解之洗洗脚(三)
对于以下代码:
public class User{ static int index = 0; public String userName; public String password; public User(String userName,String password){ this.userName = userName; this.password = password; } public static void main(String[] arg){ Set<User> users = new HashSet<User>(); //L1 User user=new User("lisa","ddd"); //L2 users.add(user); //L3 User user1=new User("lisa","ddd"); //L4 users.add(user1); //L5 System.out.println(“size---->"+users.size()); //L6 } //重写hashCode和equals方法 public int hashCode(){ system.out.println("fn ----> hashCode"); return index++; } public boolean equals(){ system.out.println("fn ----> equals"); return true; } }
我们在代码中添加了 static int index = 0; 和 在hashCode 方法中 return index++;
执行:
fn ----> hashCodefn ----> hashCode2
为什么没有执行 fn-----> equals 呢?、 难道在加入其它对象之前不用判断其是不是同一个对象了么? 而且equals()返回的是true啊,标明门禁是好的啊。那为什么数量是2呢?
答案: 还记得我们在hashCode()方法中的return index++ 了么? 即每次返回的int类型都是不一样的。即每次添加user对象到set中的时候,都是在set中另外开辟一个房间给传入的user 对象。
所以,既然每个USER都入住不同的房间,就不存在同一个房间住2个人需要门禁来判断了撒。
因此这里将永远不会调用 equals()方法了,也就不会打印 fn------->equals 了。
而set是无限扩大空间的。因此就加多少人进来,我就给你分配多少个房间。哈哈(直到内存吃光哈哈)
于是这里就回答了Q4:equals方法和hashCode方法调用的顺序是怎样的? 以及2个方法被调用的时机? 2个方法会不会有可能不被调用?或者必须2者中的某一个是不是一定会被调用?
总结:因此要不要你进来,就靠我怎样return int和return boolean了。
永远进来就 return false或者 return int(变化的数字)就OK了.
只进一个就 return true和return int(固定不变数字)就Ok了。
感谢嘉宾徐老师。
1 楼 pengjunwu 2009-12-30 大哥,你错啦!因为hashset集合是不允许重复元素的,在add的时候会先判断是否重复,顺序是这样的:
先判断hashcode 如果相等才去用equals判断(因为hashcode相等不一定equals为true)
如果hashcode不相等的话则可以判断出其equals一定是false也就是不相等的不重复的元素了
set接口是无序非重复的 hashset中add时 是通过其元素的hashcode定位其存储的位置的,先计算其hashcode去看对应位置上是否已经有元素了,如果没有则直接add;
当发现该位置上已经有元素的话则拿已存的元素与要存的元素做比较是否是同一元素如果是相同元素的话则不存,如果是不同的元素的话就继续散列(存在冲突) 2 楼 pengjunwu 2009-12-30 其实重写hashcode函数只是提高比较效率有没有无所谓(类都继承了Object的hashcode方法)
还有比较元素是否重复还是看equals的返回值。 3 楼 colincome 2010-01-02 pengjunwu 写道大哥,你错啦!因为hashset集合是不允许重复元素的,在add的时候会先判断是否重复,顺序是这样的:
先判断hashcode 如果相等才去用equals判断(因为hashcode相等不一定equals为true)
如果hashcode不相等的话则可以判断出其equals一定是false也就是不相等的不重复的元素了
set接口是无序非重复的 hashset中add时 是通过其元素的hashcode定位其存储的位置的,先计算其hashcode去看对应位置上是否已经有元素了,如果没有则直接add;
当发现该位置上已经有元素的话则拿已存的元素与要存的元素做比较是否是同一元素如果是相同元素的话则不存,如果是不同的元素的话就继续散列(存在冲突)
嘿嘿,感谢的你正解。
貌似我想阐述的和你说的是一样的,难道是我没有清楚的表达出来。