【源码分析】不同类型hashcode和equals方法

hashCode实现约定:

  • 同一对象调用多次调用hashCode方法必须始终返回相同的整数,且整数不必在应用程序的一次执行与另一次执行之间保持一致
  • equals 两对象相等,hashCode方法必须产生相同的整数结果
  • equals 两对象不相等,hashCode方法必须产生不相同的整数结果

注意:

  • 每当重写hashCode方法时,通常都需要重写equals
  • == 在基本数据类型:值内容, 引用类型时:地址
  • equals 重写:值内容 , equals不重写:地址

String类型 hashcode和equals方法

返回此字符串的散列码。String对象的哈希码计算为

s [ 0 ] ∗ 3 1 ( n − 1 ) + s [ 1 ] ∗ 3 1 ( n − 2 ) + . . . + s [ n − 1 ] s[0]*31^{(n-1)} + s[1]*31^{(n-2)} + ... + s[n-1] s[0]31(n1)+s[1]31(n2)+...+s[n1]

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

示例:
a -> 97
aa -> 97*31 + 97 = 3104
aaa -> 97 *31 31 + 9731 + 97 = 96321

符合equals比较值,而不是内存地址

// 存储字符串的字符数组
private final char value[];

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

Hashtable类型 hashcode和equals方法

Hashtable源码如下:

public synchronized boolean equals(Object o) {
	// 判断是否是同一对象引用
    if (o == this)
        return true;
	// 判断是否是Map类型,哦豁这不说明实现Map接口的Hashtable.equals(HashMap)返回true
    if (!(o instanceof Map))
        return false;
    Map<?,?> t = (Map<?,?>) o;
   	// 判断长度否相等
    if (t.size() != size())
        return false;

    try {
    	// 逐个值比较
        Iterator<Map.Entry<K,V>> i = entrySet().iterator();
        while (i.hasNext()) {
            Map.Entry<K,V> e = i.next();
            K key = e.getKey();
            V value = e.getValue();
            if (value == null) {
                if (!(t.get(key)==null && t.containsKey(key)))
                    return false;
            } else {
                if (!value.equals(t.get(key)))
                    return false;
            }
        }
    } catch (ClassCastException unused)   {
        return false;
    } catch (NullPointerException unused) {
        return false;
    }

    return true;
}

Entry hashCode()源码

public int hashCode() {
    return hash ^ Objects.hashCode(value);
}
public synchronized int hashCode() {
    int h = 0;
    // Hashtable没有插入数据为null 或 负载因子< 0 返回0
    if (count == 0 || loadFactor < 0)
        return h;  // Returns zero

    loadFactor = -loadFactor;  // Mark hashCode computation in progress
    Entry<?,?>[] tab = table;
    for (Entry<?,?> entry : tab) {
        while (entry != null) {
            h += entry.hashCode();
            entry = entry.next;
        }
    }

    loadFactor = -loadFactor;  // Mark hashCode computation complete

    return h;
}

你可能感兴趣的:(源码分析,哈希算法,散列表,算法)