Не является ли это потенциально медленным процессом?Когда рассчитывается?Как только Набор сформирован или по запросу?Неужели это на самом деле не съедает прирост производительности, который я ожидаю получить от кэширования?
В принципе, это не указано в интерфейсе Set, поэтому оно зависит от реализации.
Для реализаций множеств общего назначения в java.util
и java.util.concurrent
(а также для представлений наборов карт общего назначения), hashCode()
рассчитывается по требованию, а будет медленным для больших наборов .(Для небольших наборов с простыми элементами это на самом деле не имеет значения.)
Причина в том, что hashCode
(а также equals
), как определено, является динамическим, например, изменяется при добавлении элемента илиудаляется и изменяется также в случае изменения хэш-кода элемента (что само по себе проблематично для наборов на основе хеш-функции).Таким образом, обычно Set / List / Map на самом деле не является хорошим ключом для карты.
Для неизменяемого набора (который на практике также является единственным типом набора, который действительно подходит в качестве ключа карты),хеш-код может быть вычислен один раз (либо при создании, либо при первом использовании), а затем кэширован (как это делает String).
Можно также реализовать такое кэширование для изменяемых множеств, если хеш-кодыэлементы не меняются: формула достаточно проста, так что можно обновлять значение при каждом добавлении или удалении, не проверяя ничего, кроме добавленного / удаленного элемента.Но убедитесь, что набор не меняется, пока он используется в качестве ключа на карте.
(Большая часть этого также относится к списку и карте с их похожими формулами hashCode()
.)