고유 한 키 페어 객체를 생성 할 때 몇 가지 문제에 직면해야합니다.
먼저 hashCode()및 equals(). 이 작업을 수행해야합니다.
둘째,를 구현할 때 hashCode()작동 방식을 이해해야합니다. 주어진 사용자 예
public int hashCode() {
return this.x ^ this.y;
}
실제로 할 수있는 최악의 구현 중 하나입니다. 이유는 간단합니다. 동일한 해시가 많이 있습니다! 그리고는 hashCode()희귀하고 고유 한 경향이있는 int 값을 반환해야합니다. 다음과 같이 사용하십시오.
public int hashCode() {
return (X << 16) + Y;
}
이것은 빠르며 -2 ^ 16에서 2 ^ 16-1 (-65536에서 65535) 사이의 키에 대해 고유 한 해시를 반환합니다. 이것은 거의 모든 경우에 적합합니다. 이 범위를 벗어나는 경우는 거의 없습니다.
셋째, 구현할 때 equals()그것이 무엇을 위해 사용되는지 알고 키가 객체이기 때문에 키를 만드는 방법을 알고 있어야합니다. 진술로 인해 항상 동일한 결과를 얻을 수 있다면 종종 불필요합니다.
이와 같은 키를 생성하는 경우 : 키 map.put(new Key(x,y),V);의 참조를 비교하지 않습니다. 지도에 액세스하고 싶을 때마다 map.get(new Key(x,y));. 따라서 당신 equals()은 같은 진술이 필요하지 않습니다 if (this == obj). 그것은 것입니다 결코 발생 시킬수 없습니다.
대신 if (getClass() != obj.getClass())당신의 equals()더 나은 사용 if (!(obj instanceof this)). 하위 클래스에도 유효합니다.
따라서 비교해야하는 유일한 것은 실제로 X와 Y입니다. 따라서이 경우 가장 좋은 equals()구현은 다음과 같습니다.
public boolean equals (final Object O) {
if (!(O instanceof Key)) return false;
if (((Key) O).X != X) return false;
if (((Key) O).Y != Y) return false;
return true;
}
따라서 결국 키 클래스는 다음과 같습니다.
public class Key {
public final int X;
public final int Y;
public Key(final int X, final int Y) {
this.X = X;
this.Y = Y;
}
public boolean equals (final Object O) {
if (!(O instanceof Key)) return false;
if (((Key) O).X != X) return false;
if (((Key) O).Y != Y) return false;
return true;
}
public int hashCode() {
return (X << 16) + Y;
}
}
차원 인덱스 X와 Y공개 액세스 수준은 최종 항목이고 민감한 정보를 포함하지 않기 때문에 제공 할 수 있습니다 . 나는 확실히 여부를 100 % 아니에요 private액세스 수준이 제대로 작동 어떤 을 캐스팅 할 때 경우 ObjectA를 Key.
파이널에 대해 궁금하다면 인스턴스에 설정되고 절대 변경되지 않는 값을 final로 선언하므로 객체 상수입니다.