equals和hashcode

2018-03-02  本文已影响14人  吃橘子的冬天

Object类是java的万类之父,其中,equals和hashcode是Object类的2个非常重要的方法。

1. equals方法:

Object类中默认的实现方式是 :

public boolean equals(Object obj)  return this == obj  

也就是说,只有this 和 obj引用同一个对象,才会返回true。而我们往往需要用equals来判断 2个对象是否等价,而非验证他们的唯一性。这样我们在实现自己的类时,就要重写equals。

那么,按照约定,equals方法要满足以下规则:

  1. 自反性: x.equals(x) 一定是true;
  2. 对null: x.equals(null) 一定是false;
  3. 对称性: x.equals(y) 和 y.equals(x)结果一致;
  4. 传递性: a 和 b equals , b 和 c equals,那么 a 和 c也一定equals;
  5. 一致性: 在某个运行时期间,2个对象的状态的改变不会不影响equals的决策结果,那么,在这个运行时期间,无论调用多少次equals,都返回相同的结果。

到此,常见的面试问题就不是问题了。
问:equals相等,两个类一定相等吗?
答曰:默认情况下,equals相等,两个类一定相等;如果重写的话,那就不一定喽。

equals重写的正确姿势:

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

        if ((obj == null) || (obj.getClass() != this.getClass()))
            return false;

           //能执行到这里,说明obj和this同类且非null。
        Test test = (Test) obj;
        return num == test.num&& (data == test.data || (data != null && data.equals(test.data)));
    }

equals重写的应该避免的姿势:

if((obj == null) || (obj.getClass() != this.getClass())) 
     return false; 
if(!(obj instanceof Test)) 
     return false; // avoid 避免!

避免!仅当没有子类时正确

注:equals方法的参数类型是Object

2. hashcode方法:

这个方法返回对象的散列码,返回值是int类型的散列码。
(HashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,HashCode是用来在散列存储结构中确定对象的存储地址的)。如果没有hashcode,那么就需要调用equals方法进行对比,equals方法实现一般比较麻烦。如果有hashcode,我们可以先根据hashcode方法进行判断,如果相等,再用equals方法对比。

关于hashCode方法,一致的约定是:

  1. 重写了euqls方法的对象必须同时重写hashCode()方法。
  2. 如果2个对象通过equals调用后返回是true,那么这个2个对象的hashCode方法也必须返回同样的int型散列码。
  3. 如果2个对象通过equals返回false,他们的hashCode返回的值允许相同。(然而,程序员必须意识到,hashCode返回独一无二的散列码,会让存储这个对象的hashtables更好地工作)

总结一句话:等价的(调用equals返回true)对象必须产生相同的散列码。不等价的对象,不要求产生的散列码不相同。

上一篇下一篇

猜你喜欢

热点阅读