1. 왜 hashcode ()?
세트 세트의 요소는 무질서하고 반복 할 수 없으므로 두 요소가 반복되는지 여부를 판단하는 기초는 무엇입니까? "물론, Object.equal ()은 물체가 동일한지 비교하는 데 사용됩니다."라고 특정 Ape는 말했습니다. 그러나 세트에는 많은 객체가 있으며, 세트 세트에 추가 된 객체 요소의 비교 수는 점차 증가하여 프로그램 작동의 효율을 크게 줄입니다. Java는 해싱 알고리즘 (해싱 알고리즘이라고도 함)을 사용 하여이 문제를 해결합니다. 객체 (또는 데이터)는 특정 알고리즘에 따라 주소에 직접 매핑되며 객체의 액세스 효율이 크게 향상됩니다. 이러한 방식으로, 다수의 요소가 포함 된 세트 세트가 요소 (개체)를 추가해야 할 때 먼저이 요소의 hashcode ()를 호출하면이 요소의 실제 저장 위치를 한 번에 배치 할 수 있습니다. 이 위치에 요소가 없으면 객체가 컬렉션 세트에 처음으로 저장되고 객체 가이 위치에 직접 저장됨을 의미합니다. 이 위치에 객체가있는 경우 Equal ()을 호출하여 두 객체가 동일했는지 확인하십시오. 마찬가지라면 요소를 버리고 존재하지 않습니다. 동일하지 않은 경우 다른 주소에 해시.
2. Hashcode ()를 어떻게 사용합니까?
Java Language에는 APE 설계에서 Equal ()에 대해 준수 해야하는 5 가지 요구 사항이 있습니다.
대칭. a.equal (b)가 "true"를 반환하는 경우 B.equal (a)도 "true"를 반환해야합니다.
반사. A. 평등 (a)은 "true"를 반환해야합니다.
전이. a.equal (b)가 "true"를 반환하고 b.equal (c)가 "true"를 반환하면 c.equal (a)는 "true"를 반환해야합니다.
일관성. A.equal (b)가 "true"를 반환하는 경우, A와 B의 내용이 변경되지 않은 한 A.Equal (b)가 "true"를 반환 해야하는 경우에 관계없이.
어쨌든 A.equals (null)는 항상 "false"를 반환합니다. a.equals (다른 유형의 객체 및 a)는 항상 "false"를 반환합니다.
hashcode ()와 equals ()의 반환 값 사이의 관계.
a.equals (b)가 "true"를 반환하면 a와 b의 hashcode ()는 같아야합니다.
a.equals (b)가 "false"를 반환하면 a와 b의 hashcode ()가 같거나 불평등 할 수 있습니다.
여기 예입니다. 실제 소프트웨어 개발에서는이 두 가지 방법을 다시 작성하는 것이 가장 좋습니다.
공공 클래스 직원 {int EmployeeId; 문자열 이름; // 다른 방법이 여기에 있습니다 @override public boolean equals (object obj) {if (obj == this)는 true; 직원 EMP = (직원) OBJ; if (EmployeeId.equals (emp.getemployeeid ()) && name == emp.getName ()) true; 거짓을 반환합니다. } @override public int hashcode () {int hash = 1; 해시 = 해시 * 17 + EmployeeiD; 해시 = hash * 31 + name.hashcode (); 해시를 반환; }}3. 다음은 일반적으로 사용되는 클래스의 hashcode () 구현 방법에 중점을 둡니다.
문자열 클래스의 hascode ()
public int hashcode () {int h = hash; if (h == 0) {int off = 오프셋; char val [] = value; int len = count; for (int i = 0; i <len; i ++) {h = 31*h+val [off ++]; } 해시 = h; } 반환 h; }이 코드에서 가장 흥미로운 점은 해시의 구현 방법입니다. 최종 계산 된 해시 값은 다음과 같습니다.
S [0] 31n-1 + s [1] 31n-2 +… + s [n-1]
S [i]는 문자열의 i-th 문자이고 n은 문자열의 길이입니다. 그렇다면 왜 다른 숫자 대신 여기에서 31을 사용합니까?
31은 홀수 소수입니다. 승수가 균일하고 곱셈이 오버플로되면 2의 곱셈이 이동 작동과 동일하기 때문에 정보가 손실됩니다. 소수를 사용하는 이점은 분명하지 않지만 해시 결과는 해당 결과를 계산하는 데 일반적으로 사용됩니다. 31은 더 나은 성능을 얻기 위해 곱셈 대신 시프트 및 뺄셈을 사용하는 좋은 기능을 가지고 있습니다. 31*i == (i << 5) -i. VMS는이 최적화를 자동으로 완료 할 수 있습니다. (효과적인 자바에서)
객체 클래스의 hascode ()
hashcode ()는 객체 클래스의 기본 메소드입니다. 기본 방법을 호출하는 방법?
공개 기본 int hashcode ();
객체 클래스의 기본 메소드 클래스는 여기에서 찾을 수 있습니다. 심층 분석을 위해 다른 블로그를 읽으십시오
정적 jninativeMethod 메소드 [] = {{ "hashcode", "() i", (void *) & jvm_ihashcode}, { "wait", "(j) v", (void *) & jvm_monitorwait}, { "notify", ", (void *) & jvm_monitorn} "() v", (void *) & jvm_monitornotifyall}, { "clone", "() ljava/lang/object;", (void *) & jvm_clone},};소스 코드에는 getClass () (line58 참조) 등이 포함됩니다. HashCode () (Line43 참조)는 JVM_IHASHCODE에 대한 포인터로 정의됩니다.
JVM.CPP는 JVM_IHASHCODE (LINE 504) 함수를 정의합니다. 이 함수는 Objectsynchronizer :: fasthashcode를 호출하며, 이는 Synchronizer.cpp에서 결정됩니다. 530 행의 576 행 및 get_next_hash에서 fasthashcode를 구현하려면 530 행에서 576 행 및 get_next_hash에서 fasthashcode의 구현을 참조 할 수 있습니다.