Search code examples
javahashcode

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

why java use these two different approaches? Is there anything related to the characteristic of Set and List? Why it uses 31 but not other numbers? Thanks!


Solution

  • Sets are unordered, so {a, b, c} must have the same hash code as {c, b, a}. Addition is commutative, so adding the elements' hashCodes gives you that property.

    Lists are ordered, so while [a, b, c] may have the same hash code as [c, b, a], it does not need to -- and it'd be better if it didn't, since as much as possible non-equal objects should try to have non-equal hashCodes. The ArrayList.hashCode implementation has that property.

    Note that Set and List both define how implementations must define equals and hashCode (Set.hashCode, List.hashCode), so any (compliant) implementation of those respective collections is going to look pretty much the same. This gives you the useful property that a Set containing the same elements is equal (and thus has the same hashCode) as any other Set, regardless of the underlying implementations.