질문 : Java에서 equals 및 hashCode 메소드를 대체해야하는 이유는 무엇입니까?
최근에이 Developer Works 문서를 읽었습니다.
이 문서는 모두 hashCode()
및 equals()
효과적이고 정확하게 정의하는 것에 관한 것이지만,이 두 가지 메서드를 재정의해야하는 이유를 파악할 수 없습니다.
이러한 방법을 효율적으로 구현하기 위해 어떻게 결정을 내릴 수 있습니까?
답변
Joshua Bloch는 효과적인 자바에 대해 말한다
equals ()를 재정의하는 모든 클래스에서 hashCode ()를 재정의해야합니다. 그렇게하지 않으면 Object.hashCode ()에 대한 일반 계약을 위반하게되어 HashMap, HashSet 및 Hashtable을 포함한 모든 해시 기반 컬렉션과 함께 클래스가 제대로 작동하지 못하게됩니다.
hashCode()
를 재정의하지 않고 equals()
Map
을 사용하려고하면 어떤 일이 발생하는지 예를 들어 이해해 보겠습니다.
이와 같은 클래스가 있고 importantField
MyClass
두 객체가 동일하다고 가정합니다 (eclipse에 의해 생성 된 hashCode()
및 equals()
public class MyClass {
private final String importantField;
private final String anotherField;
public MyClass(final String equalField, final String anotherField) {
this.importantField = equalField;
this.anotherField = anotherField;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((importantField == null) ? 0 : importantField.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final MyClass other = (MyClass) obj;
if (importantField == null) {
if (other.importantField != null)
return false;
} else if (!importantField.equals(other.importantField))
return false;
return true;
}
}
이것을 가지고 있다고 상상해보십시오
MyClass first = new MyClass("a","first");
MyClass second = new MyClass("a","second");
equals
만 무시
equals
만 재정의되면 myMap.put(first,someValue)
를 호출하면 먼저 일부 버킷으로 해시되고 myMap.put(second,someOtherValue)
를 호출하면 다른 버킷으로 해시됩니다 (해시 코드가 다르기 때문) hashCode
). 따라서 동일하더라도 동일한 버킷에 해시하지 않기 때문에 맵이이를 인식 할 수 없으며 둘 다 맵에 남아 있습니다.
hashCode()
재정의하는 경우 equals()
를 재정의 할 필요는 없지만 MyClass
importantField
equals()
재정의하지 않는 경우 동일한 경우에 어떤 일이 발생하는지 살펴 보겠습니다.
hashCode
만 재정의
hashCode
만 재정의하는 경우 myMap.put(first,someValue)
를 호출 할 때 먼저 가져 와서 hashCode
계산하여 지정된 버킷에 저장합니다. myMap.put(second,someOtherValue)
를 호출 할 때 맵 문서에 따라 첫 번째를 두 번째로 바꿔야합니다 (비즈니스 요구 사항에 따라).
그러나 문제는 equals가 재정의되지 않았기 때문에 맵이 second
해시하고 second.equals(k)
가 true k
가 있는지 확인하면서 버킷을 반복 second.equals(first)
은 false
입니다.
분명했으면 좋겠어
출처 : https://stackoverflow.com/questions/2265503/why-do-i-need-to-override-the-equals-and-hashcode-methods-in-java
'프로그래밍 언어 > JAVA' 카테고리의 다른 글
Java에서 SoftReference와 WeakReference의 차이점 (0) | 2021.09.03 |
---|---|
Java String을 byte []로 변환하는 방법 (0) | 2021.09.02 |
Java에서 SuppressWarnings ( "unchecked")의 의미 (0) | 2021.08.27 |
JS 객체를 JSON 문자열로 변환 (0) | 2021.08.25 |
자바에서 List<Integer>를 int[]로 변환하는 방법? (0) | 2021.08.23 |