首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

满载equals和hashCode

2012-12-18 
重载equals和hashCode覆盖equals时总要覆盖hashCode,一个很常见的错误根源在没有覆盖hashCode方法。在每个

重载equals和hashCode
覆盖equals时总要覆盖hashCode,一个很常见的错误根源在没有覆盖hashCode方法。在每个覆盖了equals方法的类中,也必须覆盖hashCode方法。如果不这样做的话,就会违反Object.hashCode的通用约定,从而导致该类无法结合所有基于散列的集合一起正常工作,这样的集合包括HashMap、HashSet和Hashtable。

下面是约定的内容,摘自Object规范[JavaSE6]:
1)在应用程序的执行期间,只要对象的equals方法所用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法都必须始终如一地返回同一个整数。在同一个应用程序的多次执行过程中,每次执行所返回的整数可以不一致。

2)如果两个对象根据equals(Object)方法比较是相等的,那么调用这两个对象中任意一个对象的hashCode方法都必须产生同样的整数结果。

3)如果两个对象根据equals(Object)方法比较是不相等的,那么调用这两个对象中的任意一个对象的hashCode方法,则不一定要产生不同的整数结果。但是程序员应该知道,给不相同的对象产生截然不同的整数结果,有可能提供散列表(hash table)的性能。

如果覆盖equals没有覆盖hashCode,将会违反上面的第2条:相等的对象必须具有相等的散列码(hashCode)。Object类里面的默认eqals方法是比较内存地址是否相等,默认的hashCode方法则是根据内存地址产生一个整数,所以Object类本身当然是符合上面规则的。当你覆盖了equals后,内存地址不同的对象可能会相等,而如果这时你没有覆盖hashCode方法的话,hashCode还是根据内存地址来生成,就会出现相等的对象具有不同的散列码的情况。

下面给出了一个重载equals和hashCode的样本:

package core;public class OverrideEqualsAndHashCodeSample {    private String name;    private String region;    private String position;           public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getRegion() {        return region;    }    public void setRegion(String region) {        this.region = region;    }    public String getPosition() {        return position;    }    public void setPosition(String position) {        this.position = position;    }    @Override    public boolean equals(Object o) {        if(o==null) return false;        if(!(o instanceof OverrideEqualsAndHashCodeSample)) return false;        if(this==o) return true;        OverrideEqualsAndHashCodeSample o2=(OverrideEqualsAndHashCodeSample)o;        if(name.equalsIgnoreCase(o2.name)        && region.equalsIgnoreCase(o2.region)        && position.equalsIgnoreCase(o2.position))            return true;        return false;    }        @Override    public int hashCode() {      int result=17;      result=31*result+name!=null?name.hashCode():0;      result=31*result+region!=null?region.hashCode():0;      result=31*result+position!=null?position.hashCode():0;      return result;    }}

热点排行