Почему полезно иметь нулевые значения или нулевые ключи в хэш-картах? - PullRequest
29 голосов
/ 02 сентября 2010

Hashtable не допускает нулевые ключи или значения, в то время как HashMap допускает нулевые значения и 1 нулевой ключ.

Вопросы:

  1. Почему это так?
  2. Как полезно иметь такой ключ и значения в HashMap?

Ответы [ 6 ]

43 голосов
/ 02 сентября 2010

1. Почему это так?

HashMap новее, чем Hashtable, и исправляет некоторые его ограничения.

Я могу только догадываться, о чем думали дизайнеры, но вот мои догадки:

  • Hashtable вычисляет хэш для каждого ключа, вызывая hashCode для каждого ключа. Это не сработало бы, если бы ключ был нулевым, так что это могло бы стать причиной запрета нулевых значений в качестве ключей.
  • Метод Hashtable.get возвращает ноль, если ключ отсутствует. Если бы null был допустимым значением, было бы неоднозначно, означало ли null, что ключ присутствовал, но имел значение null, или если ключ отсутствовал. Неоднозначность плохая, поэтому это может быть причиной запрета значений NULL в качестве значений.

Однако оказывается, что иногда вы действительно хотите хранить пустые значения, поэтому ограничения были удалены в HashMap. Следующее предупреждение также было включено в документацию для HashMap.get:

Возвращаемое значение null не обязательно указывает, что карта не содержит сопоставления для ключа; также возможно, что карта явно отображает ключ на нуль.


2. Как полезно иметь такой ключ и значения в HashMap?

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

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

14 голосов
/ 02 сентября 2010

Ну, я думаю, Марк Байерс отлично ответил, поэтому простой пример, в котором могут быть полезны нулевые значения и ключи:

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

3 голосов
/ 06 апреля 2017

HashTable - это очень старый класс, начиная с JDK 1.0. Классы, которые находятся в JDK 1.0 , называются Legacy классы и по умолчанию они синхронизированы .

Чтобы понять это, прежде всего вам нужно понять комментарии автора к этому классу. «Этот класс реализует хеш-таблицу, которая отображает ключи на значения. Любой ненулевой объект может использоваться как ключ или как значение. Чтобы успешно хранить и извлекать объекты из хеш-таблицы, объекты, используемые в качестве ключей, должны реализовывать метод hashCode и метод equals. ”

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

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

Для HashMap он допускает один нулевой ключ, и для ключей есть нулевая проверка, если ключ нулевой, тогда этот элемент будет храниться в нулевом месте в массиве Entry.

Мы не можем иметь более одного нулевого ключа в HashMap, потому что Ключи уникальны , поэтому допускается только один нулевой ключ и допускается много значений Null.

USE - Нулевой ключ, который мы можем использовать для некоторого значения по умолчанию.

Модифицированная и улучшенная реализация HashTable была позже представлена ​​как ConcurrentHashMap .

2 голосов
/ 04 января 2014

В дополнение к ответу Марка Байерса, Null рассматривается как данные и должен быть сохранен в качестве значения для дальнейшей проверки.Во многих случаях нулевое значение можно использовать для проверки наличия ключевой записи, но ей не присвоено значение, поэтому можно предпринять некоторые действия.Это можно сделать, сначала проверив наличие ключа, а затем получив значение.Есть еще один случай, когда просто помещайте любые поступающие данные (без какой-либо проверки).Все проверки применяются к нему после его получения.

Принимая во внимание, что null в качестве ключа, я думаю, может использоваться для определения некоторых данных по умолчанию.Обычно ноль в качестве ключа не имеет особого смысла.

1 голос
/ 17 января 2014

Сэр HashMap также внутренне использует метод hashCode () для вставки элемента в HashMap, поэтому я думаю, что это не будет правильной причиной для «почему HashTable допускает нулевой ключ»

0 голосов
/ 03 июня 2016

Это сделает интерфейс Map более простым в использовании / менее подробным. null является допустимым значением для ссылочных типов. Создание карты, способной обрабатывать нулевые ключи и значения, избавит от необходимости проверки на нуль перед вызовом API. Таким образом, карта API создает меньше «сюрпризов» во время выполнения.

Например, обычно карта используется для классификации коллекции однородных объектов на основе одного поля. Когда map совместим с null, код будет более сжатым, поскольку это простой цикл без оператора if (конечно, вам нужно убедиться, что в коллекции нет нулевых элементов). Меньшее количество строк кода без обработки ветвей / исключений с большей вероятностью будет логически правильным.

С другой стороны, отсутствие значения null не сделает интерфейс карты лучше / безопаснее / проще в использовании. Непрактично полагаться на карту для отклонения нулей - это означает, что будет выдано исключение, и вы должны его поймать и обработать. Или, чтобы избавиться от исключения, вы должны будете убедиться, что ничто не является нулевым, прежде чем вызывать методы карты - в этом случае вам все равно, если карта принимает нулевое значение, поскольку вы все равно отфильтровали ввод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...