Object.hashCode()方法与System.identityHashCode(object)的区别

        String a = new String("test");
        String b = new String("test");

        System.out.println(System.identityHashCode(a));
        System.out.println(System.identityHashCode(b));
        System.out.println(a.hashCode());
        System.out.println(b.hashCode());

打印结果

1836019240
325040804
3556498
3556498

这是为什么呢,我们知道目前a和b是两个不同的String实例,他们在内存中存放的地址肯定是不相同的,System.identityHashCode方法是java根据对象在内存中的地址算出来的一个数值,不同的地址算出来的结果是不一样的。因此这里打印出的结果不一样。

System.identityHashCode的代码描述:

 /**
     * Returns the same hash code for the given object as
     * would be returned by the default method hashCode(),
     * whether or not the given object's class overrides
     * hashCode().
     * The hash code for the null reference is zero.
     *
     * @param x object for which the hashCode is to be calculated
     * @return  the hashCode
     * @since   JDK1.1
     */
    public static native int identityHashCode(Object x);

doc上如是说:返回给定对象的哈希码,该代码与默认的方法 hashCode() 返回的代码一样,无论给定对象的类是否重写 hashCode()。

但是为什么后两个相同呢?这是因为,String类中已经重新写了hashCode()方法,也就是说,String类中hashcode(),已经不是根据对象在内存中的地址计算出来的。具体代码:

   /** Cache the hash code for the string */
    private int hash; // Default to 0
/**
     * Returns a hash code for this string. The hash code for a
     * {@code String} object is computed as
     * <blockquote><pre>
     * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
     * </pre></blockquote>
     * using {@code int} arithmetic, where {@code s[i]} is the
     * <i>i</i>th character of the string, {@code n} is the length of
     * the string, and {@code ^} indicates exponentiation.
     * (The hash value of the empty string is zero.)
     *
     * @return  a hash code value for this object.
     */
    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里面存储的内容算出来的,doc里面已经给出来了详细的算法。就是说只要String里面存储的内容一样,调用hashCode()出来的结果就是一样的,大家也可以在自己电脑是试下,和上文输出的地址是一样的。

猜你喜欢

转载自blog.csdn.net/LCL_data/article/details/89205416