Java Object.hashCode()方法

更详细的内容可以参考《effective java》与《think in java》

Object类有一个hashCode()方法,它用于计算一个对象的hash值,同时,它也用于表示这个对象在内存中的位置。

如果一个类重写了equals()方法,则必须重写hashCode()方法。2个对象的equals()方法返回true的话,其hashCode()必须返回相同的值。否则对于HashSet, HashMap, HashTable等基于hash值的类就会出现问题。

当往HashSet(其它类似)add一个新元素时,jvm会判断这个元素是否已经存在于这个Set中,它会根据hashCode()返回的值去定位这个元素,看是否存在这个java对象。如果2个元素的equals()方法返回true,则它们应该是认为同一个元素的,但如果它们的hash值不相等,则导致jvm找不到旧的元素,从而认为新的元素不存在,导致重复插入数据。

看一下String的hashCode:

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;
}

String是以每个字母的值来计算hash的,因此当字母相同时,String也是equals。

我们再看一下一般应该如何定义一个hashCode()方法:

public class Employee {
    private String name;
    private String phone;
    private String address;

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof String) {
            Employee other = (Employee) obj;
            return (this.name.equals(other.name) && this.phone.equals(phone));
        }
        return false;
    }

    @Override
    public int hashCode() {
        return 7*name.hashCode() + 11*phone.hashCode();
    }

    public int hashCode2() {
        return 7* Objects.hash(name) + 11* Objects.hash(phone);
    }

    public int hashCode3() {
        return Objects.hash(name,phone);
    }
//还有各个getter与setter。

 }

我们假设当name和phone相同时,则认为这2个对象是equals的。

hashCoe()方法是传统的方法,hashCode2()和hashCode3()这2种办法都是JDK7以后支持的,可以简化代码,而且可以避免name为空之类的情形,尤其第3种。
如不需要严格控制hash值,则使用第3种。如要控制hash值,则用第2种。

你可能感兴趣的:(java,equals,HashCode)