Почему Hashtable не принимает ключ null
?
Также почему HashMap разрешает ключи null
?
Какова цель создания этих двух классов. Поведение клавиш настолько отличается?
Почему Hashtable не принимает ключ null
?
Также почему HashMap разрешает ключи null
?
Какова цель создания этих двух классов. Поведение клавиш настолько отличается?
Из Hashtable
JavaDoc:
To successfully store and retrieve objects from a hashtable, the objects used
as keys must implement the hashCode method and the equals method.
В двух словах, поскольку null
не является объектом, вы не можете вызывать .equals()
или .hashCode()
на нем, поэтому Hashtable
не может вычислить хэш, чтобы использовать его в качестве ключа.
HashMap
является более новым и имеет более сложные возможности, которые в основном являются просто улучшением функциональности Hashtable
. Таким образом, когда HashMap
был создан, он был специально разработан для обработки значений null
в качестве ключей и обрабатывал их как особый случай.
В частности, использование null
в качестве ключа обрабатывается таким образом при выдаче .get(key)
:
(key==null ? k==null : key.equals(k))
Это просто деталь реализации.
Hashtable
- это старший класс, и его использование обычно не рекомендуется. Возможно, они увидели необходимость нулевого ключа и, что более важно, - нулевые значения и добавили его в реализацию HashMap
.
Hashtable предшествует структуре коллекций и является частью JDK 1.0. В то время нулевые ключи, вероятно, считались не полезными или не существенными, и поэтому они были запрещены. Вы можете увидеть это как ошибку дизайна, так же как выбор имени Hashtable
, а не Hashtable
.
Затем, спустя несколько лет, появилась структура коллекций, и Hashtable был слегка изменен, чтобы вписаться в рамки. Но поведение с нулевыми ключами не было изменено, чтобы сохранить обратную совместимость.
Hashtable следует устареть, ИМХО.
Я дам вам знать, как хэш-память хранит объекты внутри:
HashMap сохраняет значения через put (ключ, значение) и получает значения thorugh get(key)
. Процесс следует за понятием Хешинга.
Когда мы говорим put(key,value)
- Internally hashCode()
, для ключа вычисляется и принимается за вход для hashfunction()
, чтобы найти местоположение ведра для хранения.
В случае Collision - при расчете hashCode()
может быть возможность, что ключ отличается, но hashCode()
тот же, в то время, после определения местоположения ведра, сохранение выполняется в связанном списке. Обратите внимание: при сохранении в качестве Map.Entry сохраняется значение ключа.
Когда выполняется извлечение значения через ключ, если во время столкновения, где ключ hashcode() может быть таким же, тогда значение восстанавливается с помощью функции equals()
, чтобы узнать нужное значение ключа.
С уважением, Ананд
Помимо всех подробностей, приведенных в других ответах, это то, как hashmap позволяет NULL Keys. Если вы посмотрите на метод putForNullKey()
в Hashmap (JDK 5), он сохраняет индекс "0" для нулевого ключа. Все значения для нулевого ключа хранятся внутри индекса "0" массива.
Нет ничего особенного в сохранении значения NULL, поскольку все операции put и lookup работают на основе объекта Key.
В hashtable Java не имеет этих механизмов, и, следовательно, hashtable не поддерживает NULL-ключ или значения.
Это два отдельных класса для двух разных вещей. Кроме того, HashTable синхронизируется. HashTable также приходил к HashMap, поэтому, естественно, он был бы менее продвинутым. Вероятно, не было смысла генерировать нулевой хэш-код в ранней Java.