Реалізація методу GetHashCodeQ в Visual C # (Sharp)

У документації MSDN метод object GetHashCode про описується таким обром (http://msdn2microsoftcora/en-us/library/systemobjectgethashcode(vs71)aspx): Даний метод можна підміняти в похідному класі Значущі класи повинні підміняти цей метод, щоб надати функцію хешування, відповідаючи класу і забезпечує кращий розподіл хеш-таблиці Класи, корие можуть бути використані еш-таблиці в якості ключа, також повинні підміняти цей метод, т к обєкти, що використовуються в якості ключа хеш-таблиці, повинні генерувати свій хеш-код за допомогою даного методу Але якщо обєкти, що використовуються в якості ключа, не надають придатної реалізації методу GetHashCode, можна надати іншого постачальника хеш-коду, заснованого на інтерфейс е SystemCollections IHashCodeProvider, пр і создани і Hashtable .

Але що це по суті означає Метою (у більшості випадків) методу GetHashCode () є однозначно ідентифікувати тип в колекції інших типів за допомогою унікального хеш-коду Скажімо, що нам потрібно створити таблицю обєктів одного типу Така ситуація може виникнути при створенні колекції і збереженні в ній множинних обєктів Зазвичай ці обєкти можна розділити за допомогою методу GetHashCode () Зазвичай тому, що метод GetHashCode () раба лише приблизно Щоб упевнитися в тому, що один обєкт дорівнює іншому, необхідно реалізувати метод Equals ()

Реалізацію ж хеш-коду краще делегувати допоміжному класу, випояющему вся важку роботу Надійний метод створення такого класу описаний у книзі Джошуа Блоха Java Ефективне програмування “. Суть його полягає

2 Блох Дж Java Ефективне програмування – М: Лорі, 2002

в наступному У змінній зберігається якась ненульова константа, скем 17 Потім для кожного члена даних типу виконується математична опація Її результатом є цілочисельні значення, які Послідовники множаться і складаються Виконувана операція є специфічною для типу і визначається наступним чином:

• bool – якщо істина, то повертається 0 в іншому випадку повертається 1

• byte, char, short або int – повертається значення типу

• long – возвращаетс я (int) (fMf >>> 32))

• float – повертається результат виконання над значенням методу

ConvertToInt32

• object – повертається значення, сгенерированное методом

obj ectGetHashCode()

• array – виконується індивідуальна обробка кожного елемента в циклі Ці правила реалізовані в класі HashCodeAutomater Далі наводиться скор-

щенний варіант реалізації класу:

public class HashCodeAutomater private readonly int _constant private int _runningTotal

public HashCodeAutomater() {

_constant = 37

„runningTotal = 17

}

public HashCodeAutomater AppendSuper(int superHashCode) {

_runningTotal = _runningTotal * _runningTotal + superHashCode return this

}

public HashCodeAutomater Append(Object obj) { if (obj == null) {

_runningTotal = _runningTotal * _constant

} else {

if (objGetTypeOisArray == false) {

_runningTotal = _runningTotal * _runningTotal + objGetHashCode()

} else {

if (obj is long[]) {

Append((long[]) obj )

}

/ / Інші тести були видалені для ясності

else {

/ / Н е масив примітивів Append ((Object []) obj)

}

}

}

return this

}

public HashCodeAutomater Append(long value) {

_runningTotal = _runningTotal * „constant +

((int) (value A (value » 32)))

return this

}

public HashCodeAutomater Append(long[] array) { if (array == null) {

_runningTotal = _runningTotal * _constant

}

else {

for (int i = 0 i &lt arrayLength i++) { Append(array[i])

}

}

return this

}

public HashCodeAutomater Append(Object[] array) { if (array == null) {

_runningTotal = _runningTotal * _constant

}

else {

for (int i = 0 i &lt arrayLength i++) { Append(array[i])

}

}

return this

}

public int toHashCode() { return _runningTotal

}

}

Різні реалізації методу Append Про відносяться до одного гуртування для одного типу даних – long Наприклад, є варіанти методу Append О, приймаючі як параметр значення long і масив значень long Повна реалізація класу HashCodeAutomater також мала б варіанти методу Append () для значення short і масиву значень short, а також для всіх інших типів даних Для Рядки типів угруповання реалізацій методу не мається, тому що цей тип розглядається як обєкт, що має власну реалізацію обчислення хеш-коду

Зверніть увагу в реалізаціях варіантів методу Append () на те, що результат обчислення складається з членом даних _runningTotai Повертаним значиться є змінна this, щоб методи можна було зєднати последовельно один з одним Це дозволяє клієнтові використовувати клас HashCodeAutomater, як показано в наступній реалізації методу GetHashCode ():

class HashcodeExample { public int value public string buffer

public HashcodeExample(int val, string buf) { value = val

buffer = buf

}

public override int GetHashCode() { return new HashCodeAutomater()

.Append(value)

.Append(buffer)toHashCode()

}

}

Реалізація класу HashcodeExample має два члена даних: value і buffer Ці два члени даних складають стан класу При обчисленні значення хеода екземпляра класу використовуються не всі члени даних Наприклад, якщо клас HashcodeExample має член даних, який звертається до зєднання з базою даних, то цей член даних не можна використовувати при обчисленні хеш-коду, т к тип зєднання з базою даних застосовується для отримання стану і не впливає на нього – це всього лише спосіб досягнення мети

Джерело: Гросс К С # 2008: Пер з англ – СПб: БХВ-Петербург, 2009 – 576 е: ил – (Самовчитель)

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*