java基础----比较对象 hashcode 与 equals 与 ==

来源:互联网 发布:ubuntu wicd 编辑:程序博客网 时间:2024/04/29 07:02

介绍

hashcode和equals是Object类中定义的方法;

hashCode 源码:

public native int  hashCode();


equals()源码:

public boolean  equals(Object obj) {        return (this == obj);     }

从equals源码可以看到 对于Object  equals 和 == 返回同样的结果
而因为Object是所有类型基类 其他类型的equals与==也应返回同样结果

测试

测试代码:

public static void test(Object o1,Object o2){boolean b=(o1==o2);System.out.println("a == b?"+b);System.out.println("equals?"+o1.equals(o2));System.out.println("hash相等?"+(o1.hashCode()==o2.hashCode()));}

public static void main(String[] args) throws CloneNotSupportedException {Integer i = new Integer(10);Integer j = new Integer(10);Integer k=j;System.out.println("1:整型的对象");test(i,j);System.out.println("2: 拷贝整型对象");test(j,k);System.out.println("3: 基础类型");int a=1;int b=1;test(a,b);System.out.println("4: object类型");Object o1 = new Object();Object o2 = o1;test(o1,o2);System.out.println("5: String类型");String s1=new String("s");String s2=new String("s");test(s1,s2);}

测试结果:output 却显示 两个不同的对象 只要内容相同则equals为TRUE 并且hashcode相等 

1:整型的对象
a == b?false
equals?true
hash相等?true
2: 拷贝整型对象
a == b?true
equals?true
hash相等?true
3: 基础类型
a == b?true
equals?true
hash相等?true
4: object类型
a == b?true
equals?true
hash相等?true
5: String类型
a == b?false
equals?true
hash相等?true

原因分析

 关于hashcode的说明  1、程序执行时对象的hashcode不变  2、如果A.equals(B) 那么A,B的hashcode 相等 3、A.equals(B)==FALSE A,B的hashcode 不被要求一定要不等

所以基类 再重写 equals 时 根据上面的原则也要重写hashcode() 保证 相等对象 hashcode相等

以Integer类为例  1.对象不为空且值相等 就是相等 2. hashcode函数直接返回int的值
public boolean  equals(Object obj) {          if (obj instanceof Integer) {              return value == ((Integer)obj).intValue();          }          return false;      }
<span style="font-family: Arial, Helvetica, sans-serif;">@Override</span>
946     public int More ...hashCode() {947         return Integer.hashCode(value);948     }
public static int More ...hashCode(int value) {960         return value;961     }

而在String类中hashcode是这样计算的 (没看懂原理)
   public int More ...hashCode() {1453        int h = hash;1454        if (h == 0 && value.length > 0) {1455            char val[] = value;14561457            for (int i = 0; i < value.length; i++) {1458                h = 31 * h + val[i];1459            }1460            hash = h;1461        }1462        return h;1463    }

总结



equals 方法要比较 对象的内容 而 “==” 比较的是对象的地址,使用自定义类 再重写equals时 也要相应的重写hashcode

更新:hashcode只是hash表中的地址  hashcode相同不一定是同一对象只说明在同一条hash链上(hash算法生成的值相同而已)
补充 Object.toString(); 打印了Object的hashcode

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

在自定义类中可以调用 super.toString() 或者 super.hashCode() 来区分对象地址 

例子:

public class ObjectTest implements Cloneable {/** * 测试 1、toString()函数 2、hashCode() 3、finalize() 4、equals() */public int value;ObjectTest(int value){this.value=value;}@Overridepublic int hashCode(){return value;}public boolean equals(Object obj){if(obj==null)return false;if(obj.getClass()==this.getClass()){ObjectTest test=(ObjectTest)obj;if(test.value==this.value)return true;}return false;}public String toString(){String str=String.valueOf(value);return str;}//调用object.tostring 打印object hashcode 区别对象的地址public int printAddr(){return super.hashCode();}


<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">结果:</span>
System.out.println("6: 自定义类型");ObjectTest t1=new ObjectTest(10);ObjectTest t2=new ObjectTest(10);ObjectTest t3=(ObjectTest) t1.clone();ObjectTest t4=t2;System.out.println(t3.printAddr());System.out.println(t4.printAddr());System.out.println(t2.printAddr());test(t1,t2);test(t1,t3);




0 0