2015-06-03 2 views
3

Я пытаюсь этот кодХэш записи Карта столкновения

Map headers=new HashMap(); 
headers.put("X-Capillary-Relay","abcd"); 
headers.put("Message-ID","abcd"); 

Теперь, когда я делаю get для любой из клавиш его работает отлично. Однако я вижу странное явление в отладчике Eclipse. Когда я отладки и зайти внутрь переменных и проверить внутри table входа в первый я вижу эту

->table 
--->[4] 
------>key:X-Capillary-Relay 
........... 

Однако после отладки через 2-й линии я получаю

->table 
--->[4] 
------>key:Message-ID 
........... 

Вместо того, чтобы создать новую запись его перезаписывает существующий ключ. Для любого другого ключа эта перезапись не возникает. Размер карты показан 2. и get работает для обоих ключей. Итак, в чем причина этого несоответствия в отладчике eclipse. Это проблема затмения? Или проблема хеширования. Хэш-код отличается для двух клавиш.

+0

Пока это работает, проблем нет или нет? У карты не будет отдельного ведра для каждого хэш-значения, поэтому нет проблем, если оба они окажутся в одном и том же ковше. Также я уверен, что создается новая запись - как бы вы могли получить оба значения с карты в противном случае? – Axel

+0

Если работа с кодом и хеши разные, но отладчик Eclipse неверно отображает содержимое карты, это может показаться проблемой с отладчиком. – slarge

+0

Я предлагаю рассматривать HashMap как черный ящик - пока вы понимаете, что он делает, вам не нужно понимать, как оно это делает. (НО, если вы используете когда-либо объекты в качестве ключей, DO реализуйте hashCode() и equals()) – NickJ

ответ

5

Ключи hashCode не используются как есть.

Применяется два преобразования (по крайней мере на основе Java 6 код):

static int hash(int h) { 
    // This function ensures that hashCodes that differ only by 
    // constant multiples at each bit position have a bounded 
    // number of collisions (approximately 8 at default load factor). 
    h ^= (h >>> 20)^(h >>> 12); 
    return h^(h >>> 7)^(h >>> 4); 
} 

и

/** 
* Returns index for hash code h. 
*/ 
static int indexFor(int h, int length) { 
    return h & (length-1); 
} 

Так как длина начального потенциала HashMap (16 по умолчанию), вы получить 4 для обоих ключей:

System.out.println (hash("X-Capillary-Relay".hashCode())&(16-1)); 
System.out.println (hash("Message-ID".hashCode())&(16-1)); 

Поэтому обе записи хранятся в связанном списке в том же ковше (индекс 4 массива table, как вы можете видеть в отладчике). Тот факт, что отладчик показывает только один из них, не означает, что другой был перезаписан. Это означает, что вы видите ключ первой записи связанного списка, и каждая новая запись добавляется в начало списка.

+0

Thanx много bro. –

Смежные вопросы