이 질문에는 이미 답변이 있습니다.
나는 많은 장소에서 독서 중에 말하는 것을 읽는다.equals
Java에서 메서드를 재정의해야합니다.hashCode
방법도 그렇지 않으면 "계약 위반"입니다.
그러나 지금까지 hashCode 메서드가 아니라 equals 메서드 만 재정의하면 어떤 문제도 발생하지 않았습니다.
계약이란 무엇입니까? 그리고 내가 계약을 위반할 때 어떤 문제에 직면하지 않는 이유는 무엇입니까? hashCode 메서드를 재정의하지 않은 경우 어떤 경우에 문제가 발생합니까?
당신이 가질 수있는 문제는 요소의 단일성이.equals()
과.hashCode()
예를 들어,HashMap
.
이름에서 알 수 있듯이 해시 테이블에 의존하며 해시 버킷은 개체의 함수입니다.hashCode()
.
두 개의 객체가있는 경우.equals()
,하지만 다른 해시 코드를 가지고, 당신은 잃는다!
여기서 중요한 계약 부분은 다음과 같습니다.있는 개체.equals()
반드시 같아야한다..hashCode()
.
이것은 모두에 설명되어 있습니다에 대한 javadocObject
. 과조슈아 블로흐네가해야한다고 했어.효과적인 자바. 충분했다.
==
). - fge
이 문서에 따르면, hashCode의 기본 구현은 모든 객체마다 다른 정수를 반환합니다.
꽤 현실적이지만, Object 클래스에 의해 정의 된 hashCode 메소드는 별개의 객체에 대해 고유 한 정수를 반환합니다. (이것은 일반적으로 객체의 내부 주소를 정수로 변환하지만이 구현
기술은 JavaTM 프로그래밍 언어에서 필요하지 않습니다.
그러나 어떤 때는 해시 코드가 동일한 의미를 갖는 다른 객체에 대해 동일하게되기를 원합니다. 예를 들어
Student s1 = new Student("John", 18);
Student s2 = new Student("John", 18);
s1.hashCode() != s2.hashCode(); // With the default implementation of hashCode
이러한 종류의 문제는 HashTable, HashSet과 같은 컬렉션 프레임 워크에서 해시 데이터 구조를 사용하는 경우 발생합니다.특히 HashSet과 같은 콜렉션에서는 중복 요소가 생겨 Set 계약을 위반하게됩니다.
예, 무시해야합니다. 재정의해야한다고 생각하는 경우equals()
, 그럼 당신은 재정의해야합니다.hashCode()
그 반대. 일반 계약해시 코드():
Java 어플리케이션의 실행 중에 같은 오브젝트로 2 회 이상 불려 갈 때마다 hashCode 메소드는, 오브젝트의 equals 비교로 사용 된 정보가 변경되지 않으면, 같은 정수를 일관되게 돌려 줄 필요가 있습니다. 이 정수는 응용 프로그램의 한 실행에서 동일한 응용 프로그램의 다른 실행으로 일관성을 유지할 필요가 없습니다.
2 개의 객체가 equals (Object) 메소드로 동일하면, 2 개의 객체의 각각으로 hashCode 메소드를 호출하면 (자), 같은 정수 결과가 생성되지 않으면 안됩니다.
equals (java.lang.Object) 메소드로 2 개의 객체가 동일하지 않은 경우, 2 개의 객체의 각각으로 hashCode 메소드를 호출하면, 다른 정수 결과가 생성 될 필요는 없습니다. 그러나 프로그래머는 부동 한 객체에 대해 고유 한 정수 결과를 생성하면 해시 테이블의 성능이 향상 될 수 있음을 인식해야합니다.
에서hashCode()
그것은 말한다 :
두 객체가
equals(Object)
방법, 그 다음에hashCode
각 객체에 대한 메소드절대로 필요한 것 같은 정수 결과를 내다.
(나에 의한 강조).
재정의하는 경우에만equals()
하지hashCode()
학급이이 계약에 위배됩니다.
이것은 또한 JavaDoc에서equals()
방법:
일반적으로 다음을 무시해야합니다.
hashCode
방법 이 메소드가 오버라이드 (override) 될 때마다, 일반적으로 계약을 맺다hashCode
메서드는 동일한 객체가 동일한 해시 코드를 갖는다.
계약은 다음과 같습니다. 두 객체가 같으면 동일한 해시 코드를 가져야하며 두 객체가 같지 않으면 동일한 해시 코드를 가질 수도 있고 그렇지 않을 수도 있습니다.
HashMap에서 객체를 키로 사용해보십시오 (joachim-sauer의 의견에 따라 편집). 문제가 발생하기 시작합니다. 계약은 지침이며 강제적 인 것은 아닙니다.
좀 봐.Hashtables
,Hashmaps
,HashSets
기타 등등. 그들은 모두 해시 키를 키로 저장합니다. 호출 할 때get(Object key)
매개 변수의 해시가 생성되고 지정된 해시에서 조회됩니다.
덮어 쓰지 않을 때hashCode()
키의 인스턴스가 변경되었습니다 (예를 들어 전혀 문제가되지 않는 간단한 문자열).hashCode()
동일한 객체에 대해 2 개의 서로 다른 해시 코드가 생길 수 있으며 이로 인해 제공된 키를 찾을 수 없습니다.map.get()
.
HashMap
. - Joachim Sauer