Java HashMap
опирается на две вещи:
- метод
hashCode()
, который возвращает целое число, которое генерируется из ключа и используется внутри карты
- метод
equals(..)
, который должен соответствовать вычисляемому хешу, это означает, что если два ключа имеют одинаковый хеш-код, то желательно, чтобы они были одним и тем же элементом.
Конкретные требования, взятые из Документация по API Java , следующие:
- Всякий раз, когда он вызывается для одного и того же объекта более одного раза во время выполнения приложения Java, метод hashCode должен последовательно возвращать одно и то же целое число при условии, что никакая информация, используемая в сравнениях сравнения объекта, не изменяется. Это целое число не должно оставаться согласованным при выполнении одного приложения другим исполнением того же приложения.
- Если два объекта равны в соответствии с методом equals (Object), то вызов метода hashCode для каждого из двух объектов должен давать одинаковый целочисленный результат.
- Не требуется, чтобы, если два объекта были неравны в соответствии с методом equals (java.lang.Object), то вызов метода hashCode для каждого из этих двух объектов должен давать разные целочисленные результаты. Тем не менее, программист должен знать, что выдача различных целочисленных результатов для неравных объектов может улучшить производительность хеш-таблиц.
Если вы не предоставите какую-либо конкретную реализацию, то ссылка на память объекта используется в качестве хеш-кода. Обычно это хорошо в большинстве ситуаций, но если у вас есть, например:
Expression e1 = new Expression(2,4,PLUS);
Expression e2 = new Expression(2,4,PLUS);
(на самом деле я не знаю, что вам нужно поместить в вашу хэш-карту, поэтому я просто догадываюсь)
Тогда, поскольку это два разных объекта, хотя и с одинаковыми параметрами, они будут иметь разные хеш-коды. Это может быть или не быть проблемой для вашей конкретной ситуации.
В случае, если это не просто использовать hasmap, не заботясь об этих деталях, если вам нужно предоставить лучший способ для вычисления хэш-кода и равенства вашего Expression
класса.
Вы можете сделать это рекурсивным способом (вычисляя хеш-код в результате хеш-кодов дочерних элементов) или наивным способом (возможно, вычисляя хеш-код по представлению toString()
).
Наконец, если вы планируете использовать просто простые типы в качестве ключей (как вы сказали целые числа или строки), просто не беспокойтесь, нет никакой разницы. В обоих случаях два разных элемента будут иметь одинаковый хэш-код. Некоторые примеры:
assert(new String("hello").hashCode() == new String("hello").hashCode());
int x = 123;
assert(new Integer(x).hashCode() == new Integer(123).hashCode());
Имейте в виду, что пример со строками в общем случае неверен, как я объяснял ранее, просто потому, что метод хеш-кода для строк вычисляет значение в соответствии с содержимым самой строки.