Хеш-код - это просто число, которое гарантированно будет одинаковым для каждого типа объекта, "совпадающего" с исходным объектом.
Это означает, что возвращение "0" для каждого вызова хэш-кода будет допустимым, но самоубийственным. Дело в том, что могут (и в большинстве случаев будут) дубликаты.
Если вы знаете хеш-код объекта, вы не можете получить к нему доступ. согласно моему примеру выше, если все объекты возвращали «0», вы все равно не могли бы спросить, какой объект имеет хеш-код 0. Однако вы можете запросить ВСЕ объекты с хеш-кодом 0 и просмотреть их (это то, что делает хеш-таблица, он уменьшает количество итераций, получая только те, которые имеют тот же хэш-код, а затем просматривает их).
Если бы вы установили (изменили) HashCode, он не был бы хеш-кодом, потому что значение, данное для объекта с данным «состоянием», не может измениться.
Что касается «наилучшего способа», чем меньше уникальных объектов, возвращающих один и тот же хеш-код, тем лучше будут работать ваши хеш-таблицы. Если у вас длинный список «int», вы можете просто использовать это значение int в качестве хеш-кода, и у вас будет тот редкий идеальный хеш-код, где каждый объект отображается точно на один хеш-код.
Обратите внимание, что hashtable не подходит для этой ситуации хранения целых чисел. Это лучше для ситуаций, когда вы пытаетесь хранить сложные объекты, которые не так просто однозначно идентифицировать или сравнить, используя другие механизмы.
Проблема с вашим «List of Int» заключается в том, что если у вас есть номер 5, и вы хотите посмотреть его в своей таблице, вы просто найдете там номер 5.
Теперь, если вы хотите увидеть, существует ли число 5 в вашей таблице или нет, это другой вопрос.
Для набора чисел с несколькими отверстиями вы можете создать простой логический массив. Если a [5] существует (верно), тогда a находится в списке. Если ваш набор чисел очень редок (1, 5, 10002930304), то это не очень хорошее решение, так как вы сохраните «False» в точках 2, 3, 4, а затем целую кучу из них до последнего число, но это прямой поиск, единственный шаг, который больше не занимает больше времени, независимо от того, сколько чисел вы добавили - O (1).
Вы можете сделать этот тип хранилища НАМНОГО более плотным, сделав его двоичным поиском в байтовом массиве, но если вы не очень хорошо разбираетесь в битовых манипуляциях, пропустите его. Это будет связано с тем, что выглядит следующим образом:
public boolean doesNumberExist(int number) {
return bytes[number / 8] & ( 1 << number % 8);
}
и до сих пор не хватает памяти, если ваше наибольшее число действительно велико.
Итак, для большого разреженного списка я бы использовал отсортированный целочисленный массив вместо слегка заполненного логического массива. Как только он отсортирован как массив, вы просто делаете бинарный поиск; начните с середины отсортированного массива. Если нужное число больше, разделите верхнюю половину списка по центру и проверьте это число, повторите.
Сортированный массив int занимает еще несколько шагов, но не слишком много, и не тратит память на несуществующие числа.