이것은 Java에서 매우 고전적인 질문이며 종종 인터뷰 중에 묻습니다. 실제로 많은 책이나 기사에서 Hashmap에서 사용자 정의 키 검색을 실현하기 위해 Hashcode () 및 Equals () 메소드를 과부하해야한다고 언급했습니다. 그러나 왜이 작업을 수행 해야하는지 와이 작업을 수행하지 않아 어떤 결과를 초래할 것인지에 대해 이야기하는 기사는 거의 없으므로이 기사를 작성하여 설명하겠습니다.
우선, 다음 사람 클래스를 키로 직접 사용하여 해시 맵에 저장하면 어떻게됩니까?
공개 클래스 사람 {개인 문자열 ID; 공개 사람 (문자열 ID) {this.id = id; }} import java.util.hashmap; public class main {public static void main (String [] args) {hashmap <person, string> map = new Hashmap <person, string> (); Map.put (신규 사람 ( "001"), "Firedingsea"); Map.put (신규 사람 ( "002"), "Linyin"); Map.put (신규 사람 ( "003"), "Henrylin"); Map.put (신규 사람 ( "003"), "FiredingSealy"); System.out.println (map.toString ()); System.out.println (map.get (신규 사람 ( "001")); System.out.println (map.get (신규 사람 ( "002")); System.out.println (map.get (신규 사람 ( "003")); }}그렇다면 출력 결과는 무엇입니까?
{person@6e4d4d5e = Henrylin, person@275cea3 = findersea, person@15128ee5 = findersealy, 사람@4513098 = linyin} nullnullnull여기에는 두 가지 문제가 있음을 알 수 있습니다.
1. 추가 과정에서 Key = New Person ( "003")의 키 값 쌍을 두 번 추가했습니다. 기대에 따르면, 해시 맵에는 그러한 키 값 쌍이 하나만 있어야합니다. 키 (예상)가 동일하기 때문에 반복적으로 추가해서는 안됩니다. value = "findingsealy"는 두 번째로 추가되어 원래 값 = "Henrylin"을 대체해야합니다. 그러나 입력에서는 예상 상황이 발생하지 않았지만 해시 맵에는 value = "findersealy"및 value = "Henrylin"의 두 가지 키 가치 쌍이 있으며, 주요 값은 여전히 다르기 때문에 명백히 잘못되었습니다.
2. 값 값을 얻을 때 3 인 개체를 사용하여 검색합니다. 이 세 개체는 우리가 방금 저장 한 세 가지 핵심 값과 동일하지만 (기대치에 따라) 검색은 세 가지 널 값이며 분명히 잘못되었습니다.
따라서 올바른 방법은 실제로 여러 곳에서 설명되었습니다. Person 클래스는 직접 수정되고 과부하 된 평등 및 해시 코드 메소드이며 수정 된 사람 클래스는 다음과 같습니다.
공개 클래스 사람 {개인 문자열 ID; 공개 사람 (문자열 ID) {this.id = id; } @override public boolean equals (Object o) {if (this == o) true를 반환합니다. if (o == null || getClass ()! = O.getClass ()) rETgy false; 사람 = (사람) o; if (id! = null?! id.equals (person.id) : person.id! = null) false를 반환합니다. 진실을 반환하십시오. } @override public int hashcode () {return id! = null? id.hashcode () : 0; }}그런 다음 위의 검사 절차를 다시 실행하면 결과는 다음과 같습니다.
{person@ba31 = inciversea, person@ba32 = linyin, person@ba33 = findersealy} findingesealinyinfindingsealy알 수 있듯이 지적 된 모든 하이라이트와 오류가 수정되었습니다. 그렇다면 왜 이런 일이 일어나고 있습니까?
해시 맵에서 검색 키 비교 순서는 다음과 같습니다.
1. 객체의 해시 코드를 계산하여 테이블에 존재하는지 확인하십시오.
2. 해당 해시 코드 위치의 객체가 현재 객체와 동일인지 확인하십시오.
분명히 첫 번째 단계는 hashcode () 메소드를 사용하는 것이며 두 번째 단계는 equals () 메소드를 사용하는 것입니다. 오버로드가 수행되지 않으면이 두 가지 단계 에서이 두 가지 단계에서 기본적으로 호출됩니다. 객체에서 해시 코드의 계산 방법은 객체 주소에 따라 계산됩니다. 두 사람의 객체 주소 ( "003")는 다르므로 해시 코드도 다릅니다. 당연히 해시 맵은 그것들을 동일한 키로 취급하지 않습니다. 동시에, 객체의 기본값 ()에서 객체의 주소에 따라 비교됩니다. 당연히 한 사람 ( "003")과 다른 사람 ( "003")은 같지 않습니다.
이것을 이해 한 후에는 왜 hashcode ()와 동등한 메소드를 과부하 해야하는 이유를 쉽게 파악할 수 있습니다.
• 오버로드 HashCode ()는 동일한 키에 대해 동일한 해시 코드를 가져 와서 지정한 키에 해시 맵을 배치 할 수 있도록하는 것입니다.
• 과부하 equals ()는 키에 저장된 객체와 키에 저장된 객체가 동일하다는 것을 해시 맵을 보여 주므로 키에 해당하는 키 값 쌍을 진정으로 얻을 수 있습니다.
또 다른 세부 사항이 있습니다. 개인 클래스에서 Hashcode () 메소드에 대한 강조는 다음과 같습니다.
@overridepublic int ashcode () {return id! = null? id.hashcode () : 0;}여기서 당황 할 수있는 요점은 다음과 같습니다. 왜 유형의 변수의 해시 코드를 개인 클래스의 해시 코드 값으로 사용할 수 있습니까? 새로운 사람 (새 문자열 ( "003"))와 새로운 사람 (새 문자열 ( "003"))의 해시 코드가 동일합니까?
다음 코드의 출력을 살펴 보겠습니다.
System.out.println ( "featingingsea".hashcode ()); System.out.println ( "findingsea".hashcode ()); System.out.println (새 문자열 ( "findingsea"). hashcode ()); System.out.println (New 문자열 ( "findingsea"). hashcode ()); 728795174728795174728795174728795174
네 가지 진술의 출력이 모두 동일하다는 것을 알 수 있습니다. 문자열 유형이 문자열의 내용에 따라 해시 코드 값을 반환하기 위해 HashCode ()를 과부하한다고 추측하는 것은 매우 직관적이고 합리적입니다. 따라서 동일한 내용의 문자열이 동일한 해시 코드를 갖습니다.
동시에, 이것은 또한 질문을 보여줍니다. hashcode ()가 동일하다는 것을 알 때 왜 비교를 위해 equals ()를 사용해야하는 이유는 무엇입니까? 개인 클래스의 Hashcode () 메소드의 과부하 구현에 따라 Person 클래스는 String Type Member ID의 해시 코드 값을 해시 코드 값으로 직접 사용하기 때문에 위의 예에서는 상황을 피하기 때문입니다. 그러나 사람 ( "003")과 문자열 ( "003")이 동일하지 않으므로 hashcode ()가 동일 할 때 equals ()도 비교해야합니다.
다음 예제는 위의 설명의 증거로 사용될 수 있습니다.
System.out.println (신규 사람 ( "003"). hashcode ()); // 47667system.out.println (새 문자열 ( "003"). hashcode ()); // 47667system.out.println (new Person ( "003"). Equals (새 문자열 ( "003")); // 거짓
위의 기사 Java는 맞춤형 클래스를 해시 맵의 핵심 값 예제로 사용합니다. 이것은 내가 당신과 공유하는 모든 콘텐츠입니다. 나는 그것이 당신에게 참조를 줄 수 있기를 바랍니다. 그리고 당신이 wulin.com을 더 지원할 수 있기를 바랍니다.