PHP中文网2017-04-18 10:47:27
hashCode
메소드
애플리케이션 실행 중 객체의
equals
메소드 비교 연산에 사용된 정보가 수정되지 않는 한,hashCode
메소드는 여러 번 호출될 때 일관되게 동일한 객체를 반환해야 합니다. 같은 객체에. 동일한 애플리케이션을 여러 번 실행하는 동안 각 실행에서 반환되는 정수가 일관되지 않을 수 있습니다.
equals(Object)
메소드 비교에 따라 두 개체가 동일한 경우 두 개체hashCode
의 메서드를 호출하면 동일한 정수 결과 가 생성되어야 합니다. 반대로 두 개체의hashCode
메서드가 동일한 정수 결과를 반환한다고 해서 두 개체가 동일하다는 의미는 아닙니다.equals
메서드가 오버로드될 수 있기 때문입니다.
equals(Object)
메서드 비교에 따라 두 개체가 동일하지 않은 경우 두 개체의hashCode
메서드를 호출해도 반드시 다른 정수 결과가 생성되는 것은 아닙니다. 그러나 서로 다른 개체가 서로 다른 정수 결과를 생성하도록 할 수 있으면 해시 테이블의 성능을 향상시킬 수 있습니다.
hashCode
해시 코드 계산(출처: Effective Java)
은
17
과 같은 0이 아닌 상수 값을result
이라는 이름의int
유형 변수에 저장합니다.객체의 각 키 필드
f
에 대해(은equals
메서드에 포함된 각 필드 를 나타냄) 다음 단계를 완료하세요.
이 필드에 대해
int
유형의 해시 코드 c를 계산합니다.
필드가
boolean
유형인지 여부를 평가합니다(f?1:0
).필드가
byte
,char
,short
또는 int 유형인 경우(int)f
이 계산됩니다.필드가
long
유형인지(int)(f^(f>>>32))
를 평가합니다.필드가
float
유형인지Float.floatToIntBits(f)
를 평가합니다.필드가
double
유형인 경우Double.doubleToLongBits(f)
을 계산한 다음 2.1.3 단계에 따라 결과long
유형 값에 대한 해시 값을 계산합니다.필드가 객체 참조이고 클래스의
equals
메서드가equals
를 재귀적으로 호출하여 필드를 비교하는 경우 해당 필드에 대해hashCode
도 재귀적으로 호출합니다. 더 복잡한 비교가 필요한 경우 필드에 대한 정규형(canonical representation)
을 계산한 다음 이 정규형에 대해hashCode
을 호출하세요. 이 필드의 값이null
이면0
이 반환됩니다(다른 상수도 허용됨).필드가 배열인 경우 각 요소는 별도의 필드로 처리되어야 합니다. 즉, 위의 규칙을 재귀적으로 적용하고 각 중요한 요소에 대한 해시 코드를 계산한 다음 2.2 단계에 따라 이러한 해시 값을 결합합니다. 배열 필드의 모든 요소가 중요한 경우 1.5 릴리스에 추가된
Arrays.hashCode
메서드 중 하나를 활용할 수 있습니다.다음 수식에 따라 2.1단계에서 계산된 해시 코드
c
를result
에 병합합니다.result = 31 * result + c
//여기서31
은 홀수 소수이고 매우 좋은 특징은 곱셈 대신 시프트와 뺄셈을 사용하면 더 나은 성능을 얻을 수 있다는 것입니다. `31*i == (i<<5) - i. 최신 JVM은 이 최적화를 자동으로 완료할 수 있습니다.반품
result
hashCode
구현이 일반적인 규칙을 준수하는지 확인하고 테스트합니다.
구현예
으아아아大家讲道理2017-04-18 10:47:27
Java의 int는 32비트로 고정되어 있습니다. 게다가 위도와 경도도 2배인데... 64비트가 될 것 같습니다.
해시코드와 동등의 의미는 일치합니다. Object
를 살펴보세요.당신이 쓴 동등은 사용될 수 있다고 생각합니다.
참고: Object 클래스의 계약은 실제로 매우 약한 제약 조건입니다. 계약을 위반하지 않고 hashcode() 및 equals()를 이와 같이 작성할 수 있습니다.
으아아아그래서 진짜 질문은 평등을 어떻게 정의하는가입니다. 코드는 보조입니다.
동등성이 "경도와 위도가 각각 동일함"으로 정의된 경우 제공한 코드는 사용 가능한 솔루션입니다(그러나 사용 가능한 유일한 솔루션은 아닙니다).