20

As per my understanding of ArrayList, the default capacity is 10 and when it grows beyond 10, it will create a new object with new capacity and so on..

So out of curiosity, I typed following program to check hashcode() for ArrayList object:

public class TestCoreJava {

    public static void main(String [] args){

        ArrayList al = new ArrayList();

        for(int i=0;i<15;i++){

            al.add("Temp"+i);
            System.out.println("Hashcode for "+i+" element "+al.hashCode());
        }
    }
}

According to above scenario, when I am not setting Initial capacity for ArrayList the default would be 10. So while adding 11th element, it will create a new object and increase the capacity for ArrayList.

When I print the hashcode for ArrayList object, it is giving a new hashcode() each time.

Following is the o/p:

Hashcode for 0 element 80692955
Hashcode for 1 element -1712792766
Hashcode for 2 element -1476275268
Hashcode for 3 element 1560799875
Hashcode for 4 element 1220848797
Hashcode for 5 element -727700028
Hashcode for 6 element -1003171458
Hashcode for 7 element -952851195
Hashcode for 8 element 607076959
Hashcode for 9 element 1720209478
Hashcode for 10 element -6600307
Hashcode for 11 element -1998096089
Hashcode for 12 element 690044110
Hashcode for 13 element -1876955640
Hashcode for 14 element 150430735

According to the concept of default capacity, till 10th element it should have printed same hashcode() as no new object needs to be created until that point, but it is not the case.

Cœur
  • 32,421
  • 21
  • 173
  • 232
suyash
  • 1,224
  • 1
  • 12
  • 30
  • `hashCode()` is tied to `equals()` which indicates that 2 lists with different elements but the same capacity should return different hash codes (which they do if you look at the sources) – Thomas Feb 29 '16 at 14:59
  • Possible duplicate of [What issues should be considered when overriding equals and hashCode in Java?](http://stackoverflow.com/questions/27581/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java) – Raedwald Mar 01 '16 at 09:44

2 Answers2

48

The hashCode of ArrayList is a function of the hashCodes of all the elements stored in the ArrayList, so it doesn't change when the capacity changes, it changes whenever you add or remove an element or mutate one of the elements in a way that changes its hashCode.

Here's the Java 8 implementation (it's actually implemented in AbstractList) :

public int hashCode() {
    int hashCode = 1;
    for (E e : this)
        hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
    return hashCode;
}

BTW, this is the exact code that appears in the Javadoc of hashCode() of the List interface :

int java.util.List.hashCode()

Returns the hash code value for this list. The hash code of a list is defined to be the result of the following calculation:

int hashCode = 1;
for (E e : list)
    hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
Community
  • 1
  • 1
Eran
  • 359,724
  • 45
  • 626
  • 694
  • this can give hash collision. For example if 1+3 = 2+2 that means 2 lists may have same hash . – Java Main Nov 01 '19 at 19:54
  • @JavaMain Yes, and that isn't a problem. Indeed, in Java, the method `.hashCode()` should give the same hash code for two Object that are equals for `.equals()`, but for two Objects that are different, it does not have to give different hash codes, even though it is better. – Nei Dec 30 '19 at 23:41
6

The hashCode of List implementations is defined in terms of the hashCode of its elements. This means that for ArrayList to be a conforming List implementation it's hashCode must change when its content changes.

More generally: for mutable objects, the hashCode should change whenever they change in a way that would make them not equal to their previous state.

You seem to be assuming that it uses the default hashCode of Object, which is not the case.

Additionally, even if ArrayList did not implement hashCode, the default hash code (also known as the identity hash code) of an ArrayList would not change if the internal array was re-allocated, as the ArrayList object itself stays the same, just the internal array object (that you don't get direct access to) will be replaced with a new one.

MC Emperor
  • 17,266
  • 13
  • 70
  • 106
Joachim Sauer
  • 278,207
  • 54
  • 523
  • 586