Хранение нескольких классов в HashMap - PullRequest
0 голосов
/ 09 марта 2012

У меня есть несколько общих классов, каждый из которых реализует один и тот же интерфейс, которым я бы хотел управлять через одну HashMap.

Но классы не используют одинаковые реализации equals () и hashcode () (хеш-код получен из разных членов; аналогично для equals ()).

Будет ли работать?Желательно ли это?

Ответы [ 5 ]

0 голосов
/ 09 марта 2012

Различные реализации hashCode и equals могут быть проблематичными, если вы используете классы в качестве ключей. Почему вы не используете классы в качестве значений и не определяете их ключи каким-либо другим способом, так что реализация hashCode и equals одинакова для всех ключей?

0 голосов
/ 09 марта 2012

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

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

0 голосов
/ 09 марта 2012

Я думаю, что безопасен для этого , поскольку каждый класс имеет методы hashCode и equals, которые подчиняются контрактам этих методов, и что два объекта двух разных классов никогда не будутравны друг другу.Если вы используете их в качестве ключей, есть вероятность, что вы можете получить больше конфликтующих хеш-кодов, чем в противном случае, что может сделать карту немного менее эффективной.Но я не думаю, что это сломается - они будут обрабатываться точно так же, как два объекта одного класса с конфликтующими хэш-кодами.

0 голосов
/ 09 марта 2012

Я предполагаю, что вы говорите об использовании этих классов в HashMap или HashSet.

В этом случае метод equals должен выглядеть примерно так и будет работать в вашем сценарии:

    public boolean equals(Object obj) {
        if (obj == null)
            return false;
        if (obj == this)
            return true; 
        if (obj.getClass() != getClass())
            return false;
        // perform actual comparison
        ...
    }
0 голосов
/ 09 марта 2012

Хорошая идея для предотвращения коллизий хеширования - поразрядно-хоровать любой хеш-код, который вы вычисляете, с помощью хеш-кода класса:

@Override 
public int hashCode()
{
   // Here you calculate your hashcode into variable h...
   return h ^ this.getClass().hashCode();
}

Можно сделать нечто подобное с equals, чтобы предотвратить равенство между объектамиразных классов:

@Override 
public boolean equals(Object other)
{
   if (this.getClass() != other.getClass()) return false;
   // Rest of you code here...
}

Кроме того, то, что вы делаете, совершенно разумно и правильно.

...