Java中“equals比较为true,那么hashcode就一定相等”这条真理探秘!

从刚接触java时候在面试时就时常遇到面试官问这样的问题:equals相等那么hashcode相等吗?也一直没有怀疑过这个逻辑的正确性。直道上个月,公司一个技术主管居然说:equals相等hashcode不一定相等! 这是语出惊人!我当时强烈反驳,拿出最典型的例子String,Integer等对象说明自己观点的正确性。同样这位主管也拿出了自己代码做了论证,看了看代码,最后打印的结果还真是equals比较相等,hashcode值不同。

首先我们说hashcode是个伟大的发明,这条真理也极大减化在开发过程中对象比较,用处不可谓不广。如果这条真理违背了,也就失去hash意义。为什么这位主管大人会在代码中论证了他的论点呢?最后花时间回来研究了一下,发现他在使用对象代码中只实现了equals方法,而没有重写hashcode方法,这就是问题根源所在。空说无凭,举例来说吧:

package org.hash;

import java.util.HashMap;
import java.util.Map;

public final class PhoneNumber {
 private final short areaCode;
 private final short exchange;
 private final short extension;
 private volatile int hashCode=0;
 public PhoneNumber(int areaCode,int exchange,int extension){
  rangeCheck(areaCode,999,"area code");
  rangeCheck(exchange,999,"exchange");
  rangeCheck(extension,9999,"extension");
  this.areaCode=(short)areaCode;
  this.exchange=(short)exchange;
  this.extension=(short)extension;
 }
 private static void rangeCheck(int arg,int max,String name){
  if(arg<0||arg <max)
   try {
    throw new Exception();
   } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   //not hashcode method
 }
 
 public boolean equals(Object o){
  if(o==this){
   return true;
  }
  if(!(o instanceof PhoneNumber))
   return false;
  PhoneNumber pn=(PhoneNumber)o;
  return pn.extension==extension &&
  pn.exchange==exchange &&
  pn.areaCode==areaCode;
 }
 
// public int hashCode(){
//  int result=17;
//  if(hashCode==0){
//  result=37*result+areaCode;
//  result=37*result+exchange;
//  result=37*result+extension;
//  hashCode=result;
//  }
//  return result;
// }
 public static void main(String[] args){
  PhoneNumber ph=new PhoneNumber(408,867,5309);
  PhoneNumber ph1=new PhoneNumber(408,867,5309);
  System.out.println(ph.equals(ph1));
  System.out.println(ph.hashCode());
  System.out.println(ph1.hashCode());

 }
}

 

此例如果不实现hashCode方法就会造成:equals相等hashcode不相等 所以在自己实现对象时候必须实现hashCode()方法。哎,这位主管大人还说:可能JDK里自带对象都相等,自己生成的复杂对象可以不相等。 我晕!估计他连hash值有啥作用还很模糊!基本功可见一般!

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值