hashCode()
컬렉션에 가장 적합한 메서드 구현을 결정하려면 어떻게해야합니까 (메소드와 같은 것이 올바르게 재정의되었다고 가정)?
답변
최고의 구현? 사용법 패턴에 따라 다르므로 어려운 질문입니다.
거의 모든 경우에 합리적인 구현이 Josh Bloch 의 효과적인 Java 항목 8 (제 2 판)에서 제안되었습니다 . 가장 좋은 방법은 저자가 접근 방식이 좋은 이유를 설명하기 때문에 거기서 찾아 보는 것입니다.
짧은 버전
-
a를 작성하고 0이 아닌 값을
int result
지정 하십시오 . -
들어 모든 분야
f
에서 테스트equals()
방법의 해시 코드를 계산c
하여 :- 필드 f가 a 인 경우
boolean
: 계산(f ? 0 : 1)
; - 필드 F 인 경우
byte
,char
,short
또는int
: 계산(int)f
; - 필드 f가 a 인 경우
long
: 계산(int)(f ^ (f >>> 32))
; - 필드 f가 a 인 경우
float
: 계산Float.floatToIntBits(f)
; - 필드 f가 a 인 경우
double
:Double.doubleToLongBits(f)
모든 긴 값처럼 리턴 값을 계산 하고 처리하십시오. - 필드 f가 객체 인 경우 :
hashCode()
메소드 의 결과를 사용 하거나 0이면f == null
; - 필드 f가 배열 인 경우 : 모든 필드를 별도의 요소로보고 해시 값을 재귀적인 방식으로 계산하고 다음에 설명 된대로 값을 결합하십시오.
- 필드 f가 a 인 경우
-
해시 값
c
을result
다음 과 결합하십시오 .result = 37 * result + c
-
반환
result
이로 인해 대부분의 사용 상황에 적절한 해시 값이 배포됩니다.
답변
dmeister가 권장하는 효과적인 Java 구현에 만족하면 직접 롤링하는 대신 라이브러리 호출을 사용할 수 있습니다.
@Override
public int hashCode() {
return Objects.hashCode(this.firstName, this.lastName);
}
여기에는 Guava ( com.google.common.base.Objects.hashCode
) 또는 Java 7 ( java.util.Objects.hash
) 의 표준 라이브러리가 필요 하지만 같은 방식으로 작동합니다.
답변
꽤 좋은 일을하는 Eclipse가 제공하는 기능을 사용하는 것이 좋으며 비즈니스 로직을 개발하는 데 노력과 에너지를 투입 할 수 있습니다.
답변
이것은 Android
문서 (Wayback Machine) 및 Github의 내 코드 와 연결되어 있지만 일반적으로 Java에서 작동합니다. 내 대답은 읽고 이해하기 훨씬 쉬운 코드 로 dmeister의 답변 을 확장 한 것입니다.
@Override
public int hashCode() {
// Start with a non-zero constant. Prime is preferred
int result = 17;
// Include a hash for each field.
// Primatives
result = 31 * result + (booleanField ? 1 : 0); // 1 bit » 32-bit
result = 31 * result + byteField; // 8 bits » 32-bit
result = 31 * result + charField; // 16 bits » 32-bit
result = 31 * result + shortField; // 16 bits » 32-bit
result = 31 * result + intField; // 32 bits » 32-bit
result = 31 * result + (int)(longField ^ (longField >>> 32)); // 64 bits » 32-bit
result = 31 * result + Float.floatToIntBits(floatField); // 32 bits » 32-bit
long doubleFieldBits = Double.doubleToLongBits(doubleField); // 64 bits (double) » 64-bit (long) » 32-bit (int)
result = 31 * result + (int)(doubleFieldBits ^ (doubleFieldBits >>> 32));
// Objects
result = 31 * result + Arrays.hashCode(arrayField); // var bits » 32-bit
result = 31 * result + referenceField.hashCode(); // var bits » 32-bit (non-nullable)
result = 31 * result + // var bits » 32-bit (nullable)
(nullableReferenceField == null
? 0
: nullableReferenceField.hashCode());
return result;
}
편집하다
일반적으로을 무시하면을 (를) 재정의 hashcode(...)
하려고합니다 equals(...)
. 따라서 이미 구현했거나 이미 구현 한 사람들을 위해 equals
여기 Github에서 좋은 참조가 있습니다 …
@Override
public boolean equals(Object o) {
// Optimization (not required).
if (this == o) {
return true;
}
// Return false if the other object has the wrong type, interface, or is null.
if (!(o instanceof MyType)) {
return false;
}
MyType lhs = (MyType) o; // lhs means "left hand side"
// Primitive fields
return booleanField == lhs.booleanField
&& byteField == lhs.byteField
&& charField == lhs.charField
&& shortField == lhs.shortField
&& intField == lhs.intField
&& longField == lhs.longField
&& floatField == lhs.floatField
&& doubleField == lhs.doubleField
// Arrays
&& Arrays.equals(arrayField, lhs.arrayField)
// Objects
&& referenceField.equals(lhs.referenceField)
&& (nullableReferenceField == null
? lhs.nullableReferenceField == null
: nullableReferenceField.equals(lhs.nullableReferenceField));
}
답변
먼저 equals가 올바르게 구현되었는지 확인하십시오. 에서 IBM의 developerWorks 기사 :
- 대칭 : 두 참조 a와 b의 경우 b.equals (a) 인 경우에만 a.equals (b)
- 반사성 : null이 아닌 모든 참조의 경우 a.equals (a)
- 전이성 : aequals (b) 및 b.equals (c)이면 a.equals (c)
그런 다음 hashCode와의 관계가 동일한 기사의 연락처를 존중하는지 확인하십시오.
- hashCode ()와의 일관성 : 두 개의 동일한 객체는 동일한 hashCode () 값을 가져야합니다.
마지막으로 좋은 해시 함수는 이상적인 해시 함수 에 접근하기 위해 노력해야 합니다 .
답변
about8.blogspot.com, 당신은 말했다
두 객체에 대해 equals ()가 true를 반환하면 hashCode ()는 동일한 값을 반환해야합니다. equals ()가 false를 반환하면 hashCode ()는 다른 값을 반환해야합니다
나는 당신에 동의 할 수 없습니다. 두 객체에 동일한 해시 코드가있는 경우 동일한 해시 코드를 의미 할 필요는 없습니다.
A가 B와 같으면 A.hashcode는 B.hascode와 같아야합니다.
그러나
A.hashcode가 B.hascode와 같다고해서 A가 B와 같아야한다는 의미는 아닙니다.
답변
이클립스를 사용하면 다음을 생성 equals()
하고 hashCode()
사용할 수 있습니다 .
소스-> hashCode () 및 equals () 생성
이 함수 를 사용하면 동등성 및 해시 코드 계산에 사용할 필드 를 결정할 수 있으며 Eclipse는 해당 메소드를 생성합니다.