hashcoe不是每个人都知道的

一、Object类的equals方法和hashCode方法:

 在Object类中equals方法与“==”作用一样,都是比较两个对象的地址。

java code:

public boolean equals(Object obj) {

return (this == obj);

}

 

 

在object类中hashCode方法是一个本地方法其定义是:

public native int hashCode();

 

它的实现是跟本地机器相关的,运用散列算法得到的一个值。为了理解,把它看成对象的内存地址也是可以的。事实上它也参与了Object类的toString()方法的实现:

 public String toString() {
 return getClass().getName() + "@" + Integer.toHexString(hashCode());  }

toString()的实现是在hashCode()的基础上做了处理。我们一般把Object类的toString()返回的值当成对象的地址,所以我们认为hashCode()与地址拥有一样的特性。

二、子类equals() 和hashCode()的重写:

过去我一直不知道在我们自定义类中重写equals()类的同时要重写hashCode(),不知道hashCode()对于对象的意义。直到做了这么一个实验:

HashSet set = new HashSet();

String A = new String("1");

String B = new String("2");

String C = new String("1");

set.add(A);

set.add(B);

set.add(C);

System.out.println(set.size());

程序得出的结果是 2

set集合中添加三个元素现在只有两个元素。对于A和C来说引用并不相同,而且set的定义是存储对象的引用。既然引用不重复那为什么只有两个元素?

原来set结构存储元不仅是无序和不重复那么简单。set它其实是个map结构。它执行添加也就是add()方法时,首先调用对象的hashCode(),根据返回的值直接去存储到相应的位置。若对应位置上没有元素,直接存储。如果对应的位置上有元素,意味着set存了与该元素有相同的haseCode值的对象。这时会调用对象的equals方法来比较这两个元素,如果equals方法也返回true。那么认为这两个元素是重复的,就不存储了。如果equals方法返回的是false,那么还是会把该元素存进去,散列到其他地址。

然后再来分析上面的结果,String类重写了equals方法和hashcode方法,当元素A存进set后再存C的时候,会调用c的hashcode()方法把C存到指定的位置上,这时发现A已经占到了C的位置,就是说A和C有相同的haseCode的值。因为String类重写了这两个方法。只要equals返回的是true也就是值相等那么hashcode的也一定会相等。这就是为什么A和C的hashcode会相同原因。当发现A和C的hashcode值相同时,再用equals方法比较这两个元素。毫无疑问,A和C用都是String,equals方法返回的是true。那么这时会认为A与C是重复的元素。不会去存储C。这就是为什么A和C只存了A的原因。

现在反过头来看equals和hashcode方法的重写问题。如果我们自定义的类只重写equals方法,只要值相等我们就返回true。不重写hashcode方法。然后我们存两个值相同的对象到set集合。这时就可以存进去重复的元素。

总之我们定义的类要遵循:equals返回true那么hashcode必须相同,hashcode相同equals不一定返回true。

菜鸟不才,抓头皮有感。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值