Использует ли List.retainAll () HashMap для внутреннего использования? - PullRequest
0 голосов
/ 02 апреля 2012

Я намеренно нарушаю контракт hashCode, который говорит, что если мы переопределяем equals() в нашем классе, мы должны также переопределить hashCode(), и я удостоверяюсь, что нет структур данных, связанных с Hash (например, HashMap , HashSet и т. Д.) Используют его. Проблема заключается в том, что я боюсь, что методы типа removeAll() и containsAll() списков могут использовать HashMaps для внутреннего использования, и в этом случае, поскольку я не переопределяю hashCode() в своих классах, их функциональность может нарушиться.

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

Ответы [ 3 ]

3 голосов
/ 02 апреля 2012

Из AbstractCollection.retainAll ()

 * <p>This implementation iterates over this collection, checking each
 * element returned by the iterator in turn to see if it's contained
 * in the specified collection.  If it's not so contained, it's removed
 * from this collection with the iterator's <tt>remove</tt> method.

public boolean retainAll(Collection<?> c) {
boolean modified = false;
Iterator<E> e = iterator();
while (e.hasNext()) {
    if (!c.contains(e.next())) {
    e.remove();
    modified = true;
    }
}
return modified;
}
2 голосов
/ 02 апреля 2012

Что касается

Мне придется придумать эффективную технику, чтобы получить хэш-код, используя все из них

Вам не нужно использовать всеполя, используемые equals в вашей реализации hashCode:

Это , а не требуется, чтобы, если два объекта были неравны в соответствии с методом equals, вызываяМетод hashCode для каждого из двух объектов должен давать разные целочисленные результаты.Тем не менее, программист должен знать, что выдача различных целочисленных результатов для неравных объектов может улучшить производительность хеш-таблиц.

Следовательно, ваша реализация hashCode может быть очень простой и при этом соответствовать контракту:

public int hashCode() {
  return 1;
}

Это будет гарантировать, что структуры данных на основе хеш-функции все еще работают (alebit при ухудшении производительности).Если вы добавите запись в вашу реализацию hashCode, то вы даже сможете проверить, вызывается ли она когда-либо.

1 голос
/ 02 апреля 2012

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

Однако, я думаю, что лучше было бы просто переопределить его, я уверен, что некоторые IDE даже могутсделайте это за вас (например, Eclipse).Если вы никогда не ожидаете, что ему позвонят, это не повредит.

...