(풋의 몸에서 발견 얻을 방법) :왜 HashMap은 키 객체가 제공 한 해시 코드를 다시 해쉬합니까?
int hash = hash(key.hashCode());
곳 방법을
private static int hash(int h) {
h ^= (h >>> 20)^(h >>> 12);
return h^(h >>> 7)^(h >>> 4);
}
이 효과적으로 공급 해시에 비트 연산을 실행하여 해시를 다시 계산 : hash()
는 다음 본체를 갖는다. 나는 다음과 같이 API가 그것을 주장에도 불구하고 그렇게 할 필요성을 이해 드릴 수 없습니다 :
이 달리 해시 코드에 대한 충돌이 발생하는 것이 중요 의 HashMap가 전원의 - 두 개의 길이 해시 테이블을 사용하기 때문입니다 하위 비트가 과 다르지 않습니다.
키 값은 데이터 구조의 배열에 저장되며이 배열의 항목 색인 위치는 해시에 의해 결정된다는 것을 알고 있습니다. 내가 이해하지 못하는 것은이 함수가 해시 분포에 어떤 값을 추가 할 것인가입니다.
"단지의 경우" ? 실제로 Java의 대부분의 해시 코드는 엉터리입니다. 예를 들어, java.lang.Integer를 살펴보십시오! 그러나 이것은 실제로 의미가 있습니다. Object.hashCode()가 equals-objects-have-equal-hashcodes 규칙을 따르고 가능한 한 충돌을 피하려고 노력하는 한 모든 사람의 Object.hashCode()에 진절머리 난 비트 배포가 있어도 괜찮습니다. "라고 말하는 것이 좋습니다. 그런 다음 HashMap과 같은 컬렉션 구현에만 모든 사람의 문제가 아닌 보조 해시 함수를 통해 이러한 값을 전달해야하는 부담이 있습니다. –
'해시 맵의 홀수 위치는 결코 사용되지 않을 것입니다.'이해가 안됩니다. 예제를 줄 수 있습니까? –
좋아, 내가 ""400114 ","400214 ","400314 "등과 같은 int ID 필드가있는 Employee 개체를 해싱하고 있다고 상상해보십시오 (모든 사람들은 ID의"14 "부분을 공유합니다. 내 부서의 접미사입니다.) Integer의 hashCode() 메서드는 정수 자체를 반환합니다. 따라서 직원 ID를 HashSet// HashMap의 해시 (int h)없이 키로 사용하면 스프레드가 매우 고르지 않게됩니다. 이 예제에서는 14가 짝수이기 때문에 버킷 만 사용합니다. – tucuxi