java中equals与hashCode的重写问题

这几天有一个朋友问我在重写equals和hashCode上出现了问题,最后我帮她解决了问题,同时也整理出来分享给大家

现上Object的equals与HashCode的代码

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

由上面可以看到Object的equlas方法等价于“==”,所以不能满足我们平时的需求,因此我们需要重写equals,在java中我们约定了重写equals的时候也要重写HashCode方法,可以参考String的equals与HashCode的方法,ok。。。上代码

 public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
  public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

现在说说我对这两个方法的个人理解心得

我们可以把HashCode理解为词典中的索引比如“词语”,“词典”两个词,所以当HashCode相同时,equals不一定相同,反过来equals相同。HashCode就一定相等,总结就是    equals相等,hashcode一定相等,equals不相等,hashcode不一定不相等(个人理解可能在某些问题上会有局限性)

下面是是我自己重写的一个equals与HashCode的方法,具体问题都标注在代码中了

 

public class Dog {
    public String name;
    public int age;

    public Dog(String name,int age){
        this.name=name;
        this.age=age;
    }

    @Override
    public boolean equals(Object obj) {
        if(this==obj) return true;
        /*第一个是通过比较地址来间接比较值的,毋庸置疑,如果地址是一样的话,那么值也是一样的。还有一点也能说明为什么是比较值而不是地址,
            那就是第一个判断只有返回true而没有返回false。因为如果是false的话那么说明地址是不同的,但是地址不同并不能说值不同,所以没
            有写返回false也说明了第一个是通过比较地址来间接比较值的,而不是只是简单的比较地址。*/
        if(this==null||(this.getClass()!=obj.getClass())) return false;
        /*if(!(obj instanceof Cat))  return false;  我在网上看到一些人这样写,这样写是不对的,当本类没有子类的时候可以,但是当本类
          存在子类会导致一些问题,======>>  a.equls(b) 返回true    b.equals(a) 返回false*/
        Dog dog=(Dog) obj;
        return this.age==dog.age&&this.name.equals(dog.name);
    }

    @Override
    public int hashCode() {
        return name.hashCode()*37+age;
    }
    public static void main(String[] args) {
        HashMap map=new HashMap();
        Dog d1=new Dog("x",1);
        Dog d2=new Dog("x",1);
        map.put(d1, 1);
        System.out.println(d1.equals(d2));             //=====>返回true
        System.out.println(map.get(new Dog("x",1)));  //=====>这里当补充些HashCode的时候的结果是null;只有在重写了HashCode才会出现结果"1"

    }
}

 

 

 

 

posted @ 2017-07-18 11:29  whiteme  阅读(556)  评论(0编辑  收藏  举报