Почему хэш-код () ArrayList изменяется каждый раз, когда вы добавляете новый элемент?

в соответствии с моим пониманием ArrayList, емкость по умолчанию 10 и когда она вырастет за 10, она создаст новый объект с новой емкостью и так далее..

поэтому из любопытства я набрал следующую программу, чтобы проверить hashcode() на

3 ответов


на hashCode of ArrayList - это функция hashCodes всех элементов, хранящихся в ArrayList, поэтому он не изменяется при изменении емкости, он меняется всякий раз, когда вы добавляете или удаляете элемент или мутируете один из элементов таким образом, что изменяет его хэш-код.

вот реализация Java 8 (она фактически реализована в AbstractList):

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

кстати, это точный код, который появляется в Javadoc hashCode() на :

int java.утиль.Список.hashCode ()

возвращает значение хэш-кода для этого списка. Хэш-код списка определяется как результат следующего вычисления:

int hashCode = 1;
for (E e : list)
    hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());

на hashCode of List реализаций составляет определить в виде hashCode из его элементов. Это означает, что для ArrayList будет соответствовать List реализация это hashCode должны изменение при изменении его содержимого.

в более общем плане: для изменяемых объектов hashCode должны меняться всякий раз, когда они меняются таким образом, что бы сделать их не equal в прежнее состояние.

вы, кажется, предполагаете, что он использует по умолчанию hashCode of Object, что не так.

кроме того, даже если ArrayList не выполнять hashCode хэш-код по умолчанию (также известный как идентичности хэш-код) из ArrayList не изменится, если внутренний массив будет перераспределен, как ArrayList сам объект остается прежним, только внутренний объект массива (к которому вы не получаете прямого доступа) будет заменен новым.


объяснение этому можно найти, взглянув на документы для хэш-кода

если два объекта равны в соответствии с методом equals (Object), то вызов метода hashCode для каждого из двух объектов должен привести к одному и тому же целочисленному результату.

когда ArrayLists содержание меняется, он также изменяет, какие другие объекты он равен. Для того, чтобы выполнить эту часть договора Object, an ArrayList либо должен есть это hashCode изменить, когда содержимое делает, или иметь каждый ArrayList же hashCode. Чтобы сделать его несколько полезным, они, очевидно, выбрали первое. Это можно проверить, посмотрев на List'С документами.

возвращает значение хэш-кода для этого списка. Хэш-код списка определяется как результат следующего расчета:

 int hashCode = 1;
 for (E e : list)
     hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());

это гарантирует, что list1.equals (list2) подразумевает, что список1.hashCode ()==list2.hashCode() для любых двух списков, list1 и list2, как того требует генеральный договор объекта.hashCode ().