Способ хэш-списка состоит в объединении хэшей для каждого элемента. Java implements the hash function для list как так:
public int hashCode() {
int hashCode = 1;
for (E e : this)
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
return hashCode;
}
Известные свойства:
- хэш-код для каждого пустого списка точно
1
.
- Хэш-код для списков с различным количеством элементов, скорее всего, будет другим.
- Хэш-код для списков с одинаковым количеством элементов, скорее всего, столкнется. Списки с теми же элементами в другом порядке будут сталкиваться; хэш-код для списков
[1,2]
и [2,1]
, к сожалению, идентичны.
- Это большой недостаток, но не такой большой, как вы могли бы подумать вначале. Таблицы хэш реализуют резервную копию, где он проверяет равенство хэш-кодов и второе равенство. Если различие в порядковом оформлении происходит вблизи передней части списков, эта резервная проверка выполняется быстро. В худшем случае, только количество сравнений сравнивается с длительностью списков.
В целом, это будет довольно хорошая хэш-функция для вашего прецедента, даже если вы используете числовое значение каждой записи гистограммы для своего хеш-кода. Проблема, которую вы действительно хотите избежать с помощью хеш-функций, является общей-делимостью, то есть вы хотите, чтобы выходы из вашей хеш-функции попадали в разные ведра хэш-таблицы. Wikipedia article покрывает свойства хорошей хэш-функции, если вы хотите получить дополнительную информацию.
Чтобы получить лучший хеш-код для списка номеров, мы должны посмотреть на better hash code for an individual number, в частности this answer.
unsigned int hash(unsigned int[] list) {
unsigned int hashCode = 0;
for (int i = 1; i < list.length; i++) {
hashCode = hashCode + list[i];
hashCode = ((hashCode >> 16)^hashCode) * 0x45d9f3b;
hashCode = ((hashCode >> 16)^hashCode) * 0x45d9f3b;
hashCode = ((hashCode >> 16)^hashCode);
}
return hashCode;
}
Я думаю что это хорошая адаптация, но я не ожидал.
Что касается эффективности переполнения, это не серьезное замедление, если только вам не придется обрабатывать исключения. В Java, arithmetic will never throw an overflow exception, вместо этого просто оберните его до минимального или максимального значения. Нет никакого реального недостатка в наличии отрицательного hashcode, если ваша реализация хэш-таблицы поддерживает его.
Ваш вопрос довольно расплывчатым. Является ли ваша гистограмма просто списком или многомерным массивом чисел? Что не так, умножая каждое число на простое и добавляя его к общей сумме, которая позволяет переполнять? Это самый простой подход хэширования. –
Просто список! Этот подход вызывает переполнение, а значения хэша отрицательны! Интересно, это неэффективно! (новичок) Извините за неопределенный вопрос.довольно запутанный и вне времени И на гистограмме хранится 16384 ящиков! – WizzyVid