Установка типа ключа в HashMap, как? - PullRequest
1 голос
/ 29 марта 2011

привет, я хочу создать HashMap (java), в котором хранится Expression, маленький объект, который я создал.Как выбрать тип ключа для использования?Какая для меня разница между целым числом и строкой?Я думаю, я просто не до конца понимаю идею HashMap, поэтому я не уверен, какие ключи использовать.Спасибо!

Ответы [ 4 ]

4 голосов
/ 29 марта 2011

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());

Имейте в виду, что пример со строками в общем случае неверен, как я объяснял ранее, просто потому, что метод хеш-кода для строк вычисляет значение в соответствии с содержимым самой строки.

1 голос
/ 29 марта 2011

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

Map<String,Integer> numbersByName = new HashMap<String,Integer>();

numbersByName.put("one",Integer.valueOf(1));
numbersByName.put("two",Integer.valueOf(2));
numbersByName.put("three",Integer.valueOf(3));
... etc

Тогда позже вы можете получить их, выполнив

Integer three = numbersByName.get("three");

Или вам может понадобиться пойти другим путем. Если вы знаете, что у вас будут целочисленные значения и вам нужны имена, вы можете отобразить целые числа в строки

Map<String,Integer> numbersByValue = new HashMap<String,Integer>();

numbersByValue.put(Integer.valueOf(1),"one");
numbersByValue.put(Integer.valueOf(2),"two");
numbersByValue.put(Integer.valueOf(3),"three");
... etc

И вытащить это

String three = numbersByValue.get(Integer.valueOf(3));
0 голосов
/ 29 марта 2011

Если вы не хотите искать выражения, почему вы хотите, чтобы они сохранялись на карте?Но если вы хотите, то ключ - это тот элемент, который вы используете для поиска.

0 голосов
/ 29 марта 2011

Ключи и связанные с ними значения являются объектами. Когда вы получаете что-то из HashMap, вы должны привести его к фактическому типу объекта, который он представляет (мы можем сделать это, потому что все объекты в Java наследуют класс Object). Итак, если ваши ключи являются строками, а ваши значения являются целыми числами, вы должны сделать что-то вроде:

Integer myValue = (Integer)myMap.get("myKey");

Однако вы можете использовать шаблоны Java, чтобы сообщить компилятору, что вы собираетесь использовать только строки и целые числа:

HashMap<String,Integer> myMap = new HashMap<String,Integer>();

См. http://download.oracle.com/javase/1.4.2/docs/api/java/util/HashMap.html для более подробной информации о HashMap.

...