hashCode()와 equals()의 차이 와 역할
HashSet 과 HashMap 은 JDK 에서 가장 많이 사용 되 는 두 가지 유형 으로 HashSet 은 같은 대상 을 저장 할 수 없 도록 요구 하고 HashMap 은 같은 키 를 저장 할 수 없 도록 요구 합 니 다. 그렇다면 자바 가 실 행 될 때 환경 은 HashSet 의 같은 대상,HashMap 의 같은 키 를 어떻게 판단 합 니까?'같은 것'을 저장 한 후에 자바 가 실 행 될 때 환경 은 어떻게 유지 합 니까? 이 문 제 를 연구 하기 전에 먼저 JDK 가 equals(Object obj)와 hashcode()두 가지 방법 에 대한 정의 와 규범 을 설명 합 니 다. 자바 의 모든 대상 은 equals(Object obj)와 hashcode()두 가지 방법 을 가지 고 있 습 니 다.왜냐하면 그들 은 Object 류 에서 정의 되 기 때 문 입 니 다. equals(Object obj)방법 은 두 대상 이'동일'한 지 판단 하 는 데 사용 되 며,'동일'하면 true 로 돌아 가 고,그렇지 않 으 면 false 로 돌아 갑 니 다. hashcode()방법 은 int 수 를 되 돌려 줍 니 다.Object 클래스 의 기본 값 은'이 대상 의 내부 주 소 를 정수 로 변환 하여 되 돌려 줍 니 다'입 니 다. 그 다음 에 두 가지 방법 에 관 한 중요 한 규범 이 있다. 규범 1:equals(Object obj)방법 을 다시 쓰 려 면 hashcode()방법 을 다시 써 서 equals(Object obj)방법 으로 결 과 를 true 로 판단 하 는 두 대상 이 같은 hashcode()반환 값 을 가지 고 있 는 지 확인 할 필요 가 있 습 니 다.쉽게 말 하면"두 대상 이 같다 면 그들의 hashcode 는 같 아야 한다"는 것 이다.그러나 주의:이것 은 규범 일 뿐 입 니 다.만약 당신 이 equals(Object obj)를 true 로 되 돌려 주 고 hashcode()는 서로 다른 두 값 을 되 돌려 주 려 고 한다 면 컴 파일 과 실행 은 틀 리 지 않 을 것 입 니 다.그러나 이렇게 자바 규범 을 위반 하면 프로그램 도 BUG 를 묻 게 된다. 규범 2:equals(Object obj)가 false 로 돌아 가면 두 대상 이'다르다'는 것 입 니 다.이 두 대상 에 대해 hashcode()방법 으로 두 개의 다른 수 를 얻 으 라 고 요구 하지 않 습 니 다.간단하게 말하자면,"만약 두 대상 이 같 지 않다 면,그들의 hashcode 는 같 을 수 있다." 이 두 가지 규범 에 따라 다음 과 같은 추론 을 얻 을 수 있다. 1.만약 에 두 대상 이 equals 라면 자바 가 실 행 될 때 환경 은 그들의 hashcode 가 반드시 같다 고 생각 합 니 다. 2.두 대상 이 equals 가 아니라면 그들의 hashcode 는 같 을 수 있 습 니 다. 3.만약 에 두 대상 의 hashcode 가 같다 면 그들 은 반드시 equals 가 아니다. 4.만약 에 두 대상 의 hashcode 가 같 지 않 으 면 그들 은 반드시 equals 가 아 닐 것 이다. 이렇게 하면 자바 가 실 행 될 때 환경 이 HashSet 과 HastMap 의 두 대상 이 같 거나 다르다 는 것 을 어떻게 판단 하 는 지 추측 할 수 있다.내 추측 은 hashcode 가 같은 지 아 닌 지 를 판단 한 다음 에 equals 여 부 를 판단 하 는 것 이다. 테스트 프로그램 은 다음 과 같 습 니 다.우선 hashCode()와 equals(Object obj)방법 을 정의 합 니 다.
자바 코드
class A {
@Override
public boolean equals(Object obj) {
System.out.println(" equals");
return false;
}
@Override
public int hashCode() {
System.out.println(" hashcode");
return 1;
}
}
그리고 테스트 클래스 를 작성 합 니 다.코드 는 다음 과 같 습 니 다.
자바 코드
public class Test {
public static void main(String[] args) {
Map<A,Object> map = new HashMap<A, Object>();
map.put(new A(), new Object());
map.put(new A(), new Object());
System.out.println(map.size());
}
}
실행 후 인쇄 결 과 는: 판단 hashcode 판단 hashcode 판단 equals 2 자바 가 실 행 될 때 환경 이 new A()라 는 대상 의 hashcode()방법 을 호출 하 는 것 을 알 수 있 습 니 다.그 중: 인쇄 된 첫 번 째 줄'판단 hashcode'는 첫 번 째 map.put(new A(),new Object()에서 인쇄 된 것 입 니 다. 다음'판단 hashcode'와'판단 equals'는 두 번 째 map.put(new A(),new Object()에서 인쇄 되 었 습 니 다. 그렇다면 왜 이런 인쇄 결과 일 까?나 는 이렇게 분석 했다. 1.첫번째 map.put(new A(),new Object()가 실 행 될 때 환경 은 이 map 에 현재 추 가 된 new A()대상 과 같은 키 가 있 는 지 판단 합 니 다.판단 방법:new A()대상 의 hashcode()방법 을 호출 하여 map 에 현재 new A()대상 과 같은 HashCode 가 존재 하 는 지 판단 합 니 다.분명히 이 때 는 같은 것 이 없 었 다.왜냐하면 이 맵 에는 아직 물건 이 없 었 기 때문이다.그래서 이때 hashcode 가 같 지 않 으 면 없습니다.
equals(Object obj)방법 을 다시 호출 해 야 합 니 다.추론 4 참조(두 대상 hashcode 가 같 지 않 으 면 그들 은 반드시 평등 하지 않 을 것 이다) 2.두 번 째 map.put(new A(),new Object()를 실 행 했 을 때 자바 가 실 행 될 때 환경 이 다시 판단 하 는 것 을 발 견 했 습 니 다.이때 map 에 똑 같은 hashcode(A 류 의 hashcode()방법 을 다시 썼 기 때문에 equals(Object obj)방법 으로 판단 할 필요 가 있 습 니 다.추론 3(만약 두 대상 의 hashcode 가 같다 면 그들 은 반드시 equals 가 아니다)을 참고 한 후에 두 대상 이 equals 가 아니 라 는 것 을 발견 했다.(내 가 equals(Object obj)방법 을 다시 썼 기 때문에 영원히 false 로 돌아 갈 것 이다.) 3.이때 판단 이 끝나 고 판단 결과:두 번 입 금 된 대상 은 같은 대상 이 아니다.그래서 마지막 으로 맵 의 길 이 를 인쇄 할 때 결 과 는 2 입 니 다. 리 셋 프로그램 은 다음 과 같 습 니 다.
import java.util.HashMap;
import java.util.Map;
class A {
@Override
public boolean equals(Object obj) {
System.out.println(" equals");
return true;
}
@Override
public int hashCode() {
System.out.println(" hashcode");
return 1;
}
}
public class Test {
public static void main(String[] args) {
Map<A,Object> map = new HashMap<A, Object>();
map.put(new A(), new Object());
map.put(new A(), new Object());
System.out.println(map.size());
}
}
자바 코드
실행 후 인쇄 결 과 는: 판단 hashcode 판단 hashcode 판단 equals 1 분명히 이때 맵 의 길 이 는 1 이 되 었 습 니 다.자바 가 실 행 될 때 환경 이 똑 같은 대상 두 개 를 저장 했다 고 생각 하기 때 문 입 니 다.원인 은 상술 한 분석 방식 에 근거 하여 분석 할 수 있다. 이상 에서 분석 한 것 은 HashMap 이다.사실 HashSet 의 밑바닥 자체 가 HashMap 을 통 해 이 루어 진 것 이기 때문에 그의 판단 원 리 는 HashMap 과 같 고 hashcode 를 먼저 판단 한 다음 에 equals 를 판단 한다. 그래서:프로그램 을 쓸 때 가능 한 한 규범 에 따라 야 합 니 다.그렇지 않 으 면 자신 도 모 르 는 사이 에 bug 를 묻 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.