2016-07-12 4 views
3

Я только что понял HashMap<K,V> проверяет k.hashCode() = key.hashCode() и k == key.HashMap <K,V> только hashCode()

Итак, независимо от того, k is "equivalent" to key, k must be == to key.

Можно ли изменить это поведение, чтобы использовать только эквивалентную эквивалентность hashCode()?

+0

Этот вопрос не совсем такой же, как выдвинутого боян. Этот вопрос говорит о том, почему 'equals()' должно быть совместимо с 'hashCode()', но это о том, как реализовать/использовать «карту», ​​так что ключи, имеющие один и тот же хэш-код, считаются эквивалентными для целей карты. Они связаны, но тесно. –

ответ

2

Так что независимо k ли "эквивалентны" key, k должен быть == к key.

Нет, это неверно, поскольку @KevinWallis уже наблюдается. HashMap использует hashCode() для определения правильного хэш-ведра и equals(), а не ==, чтобы сравнить ключи, которые попадают в одно и то же ведро. Предполагается, что типы, имеющие смысловой смысл, в которых эквивалентные экземпляры эквивалентны, описывают это через их методы equals(), и на самом деле это делают стандартные типы библиотек, такие как String и Integer. Когда ключи имеют такой тип, вам не нужно использовать один и тот же объект для извлечения значения из HashMap, которое вы его сохранили.

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

Можно ли изменить это поведение, чтобы использовать только эквивалентность hashCode()?

В этой связи невозможно изменить поведение HashMap. Если бы вы смогли это сделать, то получившаяся карта не смогла бы правильно выполнить контракт Map. Однако вы можете реализовать свой собственный класс, подобный карте, который ведет себя так, как вы описываете, или вы можете создать класс-оболочку для использования в качестве типа ключа-заменителя.

Пример ключевой класс:

class HashEquivalenceKey<T> { 
    private final T object; 

    public HashEquivalenceKey(T object) { 
     this.object = object; 
    } 

    public int hashCode() { 
     return ((o == null) ? 0 : object.hashCode()); 
    } 

    public boolean equals(Object o) { 
     return ((o != null) && (this.hashCode() == o.hashCode())); 
    } 
} 
1

Можно ли изменить это поведение для того, чтобы использовать только хэш-код() эквивалентность?

Да, вы можете переопределить equals вернуться верно, когда обе сравниваемые объекты имеют один и тот же hashCode(). Независимо от того, будет ли это иметь смысл, это другой вопрос.

public class SomeKeyClass 
{ 
    boolean equals (Object other) 
    { 
     if (!(other instanceof SomeKeyClass)) // you can skip this condition too, but it 
               // makes sense to require the two objects to 
               // be of the same class in order for them to 
               // be equal 
      return false; 
     return hashCode() == other.hashCode(); 
    } 
} 
Смежные вопросы