为什么Java 实现Set 和ArrayList 不同的hashcode 方法?

Why Java implement different hashcode method of Set and ArrayList?

 // this is the hashCode method of Set
public int hashCode() {
    int h = 0;
    Iterator<E> i = iterator();
    while (i.hasNext()) {
        E obj = i.next();
        if (obj != null)
            h += obj.hashCode();
    }
    return h;
}



//this is the hashCode method of List
public int hashCode() {
    int hashCode = 1;
    for (E e : this)
        hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
    return hashCode;
}

为什么 java 使用这两种不同的方法? Set和List的特性有什么关系吗? 为什么它使用 31 而不是其他数字? 谢谢!

集合是无序的,因此 {a, b, c} 必须具有与 {c, b, a} 相同的哈希码。加法是可交换的,因此添加元素的 hashCodes 可以得到 属性.

列表是有序的,因此虽然 [a, b, c] 可能 具有与 [c, b, a] 相同的哈希码,但它不需要——而且它会如果不这样做会更好,因为尽可能多的不相等的对象应该尝试具有不相等的哈希码。 ArrayList.hashCode 实现有 属性.

请注意,Set 和 List 都定义了实现必须如何定义 equalshashCode (Set.hashCode, List.hashCode),因此这些各自集合的任何(兼容)实现看起来都很漂亮几乎相同。这为您提供了有用的 属性,即包含相同元素的 Set 与任何其他 Set 相等(因此具有相同的 hashCode),而不管底层实现如何。