Почему Hashtable не принимает нулевой ключ?

Почему Hashtable не принимает ключ null?

Также почему HashMap разрешает ключи null?

Какова цель создания этих двух классов. Поведение клавиш настолько отличается?

Ответ 1

Из 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))

Ответ 2

Это просто деталь реализации.

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

Ответ 3

Hashtable предшествует структуре коллекций и является частью JDK 1.0. В то время нулевые ключи, вероятно, считались не полезными или не существенными, и поэтому они были запрещены. Вы можете увидеть это как ошибку дизайна, так же как выбор имени Hashtable, а не Hashtable.

Затем, спустя несколько лет, появилась структура коллекций, и Hashtable был слегка изменен, чтобы вписаться в рамки. Но поведение с нулевыми ключами не было изменено, чтобы сохранить обратную совместимость.

Hashtable следует устареть, ИМХО.

Ответ 4

Я дам вам знать, как хэш-память хранит объекты внутри:

HashMap сохраняет значения через put (ключ, значение) и получает значения thorugh get(key). Процесс следует за понятием Хешинга.

Когда мы говорим put(key,value) - Internally hashCode(), для ключа вычисляется и принимается за вход для hashfunction(), чтобы найти местоположение ведра для хранения.

В случае Collision - при расчете hashCode() может быть возможность, что ключ отличается, но hashCode() тот же, в то время, после определения местоположения ведра, сохранение выполняется в связанном списке. Обратите внимание: при сохранении в качестве Map.Entry сохраняется значение ключа.

Когда выполняется извлечение значения через ключ, если во время столкновения, где ключ hashcode() может быть таким же, тогда значение восстанавливается с помощью функции equals(), чтобы узнать нужное значение ключа.

С уважением, Ананд

Ответ 5

Помимо всех подробностей, приведенных в других ответах, это то, как hashmap позволяет NULL Keys. Если вы посмотрите на метод putForNullKey() в Hashmap (JDK 5), он сохраняет индекс "0" для нулевого ключа. Все значения для нулевого ключа хранятся внутри индекса "0" массива.

Нет ничего особенного в сохранении значения NULL, поскольку все операции put и lookup работают на основе объекта Key.

В hashtable Java не имеет этих механизмов, и, следовательно, hashtable не поддерживает NULL-ключ или значения.

Ответ 6

Это два отдельных класса для двух разных вещей. Кроме того, HashTable синхронизируется. HashTable также приходил к HashMap, поэтому, естественно, он был бы менее продвинутым. Вероятно, не было смысла генерировать нулевой хэш-код в ранней Java.