这几天有一个朋友问我在重写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" } }