해시 계산은 어레이에 배치해야 할 요소를 계산하는 것입니다. 정확하게 말하면, 그것은 어떤 링크 목록에 넣습니다. Java 규칙에 따르면, 객체를 해시 맵에 넣으려면 객체의 클래스는 해시 코드 방법을 제공하고 정수 값을 반환해야합니다. 예를 들어 문자열 클래스에는 다음 방법이 있습니다.
public int hashcode () {int h = hash; int len = count; if (h == 0 && len> 0) {int off = 오프셋; char val [] = value; for (int i = 0; i <len; i ++) {h = 31*h+val [off ++]; } 해시 = h; } 반환 h; } 위의 For Loop에주의를 기울이십시오. 약간 엉망이되지 않습니까? 그것이 무엇을하고 있는지 쉽게 이해할 수 있도록 예를 들어 보겠습니다. 예를 들어, 31 자리 계산 방법을 사용 하여이 문자열의 합을 계산하는 문자열 "ABCDE"가 있습니다. 다음 계산 공식을 작성합니다.
a*31^4+b*31^3+c*31^2+d*31^1+e*31^0. 여기서 A, B, C, D 또는 E는 ASCII 값을 참조하십시오. 매우 흥미로운 루프, N-figit을 계산하는 데 사용할 수 있습니다. 이 루프는 파티션 계산을위한 좋은 도구로 별도로 추출 할 수 있습니다.
public static void main (String [] args) {int [] a = {1,0}; System.out.println (계산 (2, a)); } private static int 계산 (int radix, int [] a) {int sum = 0; for (int i = 0; i <a.length; ++ i) {sum = sum*radix+a [i]; } 반환 합계; } 정적 메소드 cAculate는 카디 틱스로 래디를 받아들이고, 배열 A는 계산할 계산 수를 시뮬레이션하고 일관된 표면 순서에주의를 기울입니다. 예를 들어, 01 바이너리 스트링은 {0,1}에 따라 배열에 배열되어야합니다. 위의 출력은 1이며 실제 값은 01입니다.
그렇다면 왜 31이 기지로 사용합니까? 먼저 해시 코드가 필요한 이유를 이해해야합니다. 각 객체는 값에 따라 해시 코드를 계산합니다. 이 코드 크기에는 고유성이 필요하지 않지만 (일반적으로 매우 느리기 때문에) 가능한 한 많은 것이되어야하며 가능한 한 반복해서는 안되므로 카디널리티는 가능한 한 커야합니다. 또한, 31*n은 컴파일러에 의해 최적화되어 5 비트로 왼쪽으로 이동 한 다음 1만큼 감소시킬 수 있으며, 이는 성능이 향상됩니다. 실제로 31을 선택하는 것은 여전히 논란의 여지가 있습니다. 여기에서 참조하십시오.
나는이 일이 여전히 더 많은 반복으로 이어질 것이며 더 많은 숫자를 사용해야한다고 생각합니다. 따라서 앞으로 Java 구현에 약간의 변화가있을 수 있습니다. 다음 기사는 두 가지 결론을 소개합니다.
1. 카디널리티에 소수를 사용하십시오
소수의 특성 (1 만 및 요인 만)은 다른 숫자를 다른 숫자로 곱함으로써 얻은 결과를 다른 방법보다 독창성을 더 쉽게 생성함으로써 얻은 결과를 얻을 수 있습니다. 즉, 해시 코드 값 사이의 충돌 가능성이 가장 작습니다.
2. 선택 31은 분포 결과를 관찰 한 후 선택입니다. 그 이유는 명확하지 않지만 실제로 유익합니다.
또한, 첫 번째 계산 된 값은 내부적으로 캐시됩니다. 이는 최종 (불변) 클래스, 즉 문자열 객체의 내용이 변경되지 않기 때문입니다. 이것은 해시 맵을 여러 번 넣을 때 성능을 향상시킬 수 있지만 거의 사용되지 않는 것 같습니다.
요약
위의 모든 것은 해시 코드를 정의 할 때 31 계수가 사용되는 이유에 관한 것입니다. 모든 사람에게 도움이되기를 바랍니다. 관심있는 친구들은이 사이트를 계속 참조 할 수 있습니다.
" hashcode () 및 equals () 메소드를 다시 쓰는 것에 대한 자세한 소개 "
" hashcode ()와 equals () 간의 필수 차이와 연결에 대한 자세한 설명 "
" 해시 맵 사용의 Java 소스 코드 분석 "
단점이 있으면 메시지를 남겨 두십시오. 이 사이트를 지원해 주신 친구들에게 감사드립니다!