Java软件低级错误(十 ):正确定义hashcode

来源:互联网 发布:java 自定义日志文件 编辑:程序博客网 时间:2024/06/15 01:55

 解读:
类A覆写了hashCode方法,并采用A的属性value来生成A的hashCode。使用HashSet作为集合对象,把类A的一个对象a加入到HashSet中后,如果对象a的属性value发生了变化,则a的hashCode()方法返回的值也就发生变化,则无法将对象a从HashSet中删除。

 

案例:

问题代码:

//重新hashCode

public int hashCode()
{
    int result;
    result = name.hashCode() + address.toLowerCase().hashCode();
    return result;
}

..................

HashSet<Email> set = new HashSet<Email>();
set.add(new Email("abc","xxx.com"));
for(Iterator<Email> i = set.Iterator();i.hashNext();)
{
    Email mail = i.next();
    mail.address = "kkk.com";
    set.remove(mail); 
}
System.out.println(set.size());


该程序片段最后的结果是1,修改了HashSet中对象的值后,将对象从HashSet中删除失败了。


正确代码:

预防措施如下:

1、如果覆写了equals方法,必须同时覆写hashCode方法。
2、equals方法和hashCode方法应避免使用易变的属性,避免该对象的hashCode频繁变化。
3、当对象被加入到HashSet(或作为Key加入到HashMap)后,应该避免该对象的hashCode发生变化。

//如果需要对Email的address属性进行修改,那么在重新hashCode方法时,避免使用易变的属性address
public int hashCode()
{
    int result;
    result = name.hashCode();
    return result;
}