자바

JAVA 자바 Object 클래스 객체 해시코드 hashCode()

알통몬_ 2017. 3. 14. 10:09
반응형

객체 해시코드 hashCode()

hashCode() 메서드는 객체의 메모리 번지를 이용해서 해시코드를 만들어 리턴하기 때문에 

객체마다 다른 값을 가지고 있습니다. 

논리적 동등 비교시에는 hashCode() 를 오버라이딩할 필요성이 있습니다. 

이부분에 대해서는 다음에 공부하도록 하겠습니다. 

hashCode() 메서드를 실행해서 리턴된 해시코드 값이 같은지 본 후 

해시코드 값이 다르면 다른 객체로 판단하고, 같으면 equals() 메서드로 다시 비교합니다.

때문에 hashCode() 메서드가 true가 나와도 equals() 의 리턴값이 다르면 다른 객체가 됩니다.


                         같음                          true

hashCode() 리턴값 ------->   equals() 리턴값 --------> 동등 객체 

       |                                 | false

 다름 |                                 |

       ------------------->  다른 객체



public class Key {

public int number;

public Key(int number) {

this.number = number;

}

@Override

public boolean equals(Object obj) {

if(obj instanceof Key) {

Key compareKey = (Key) obj;

if(this.number == compareKey.number) {

return true;

}

return false;

}

}

이런 경우 HashMap 의 식별키로 Key 객체를 사용하면 저장된 값을 찾아오지 못합니다. 

이유는 number 필드값이 같더라도 hashCode() 메서드에서 리턴하는 해시코드가 다르기 때문에 

다른 식별키로 인식하기 때문입니다. 아래 실행 예제를 보겠습니다.

import java.util.HashMap;


public class KeyExample {

public static void main(String[] args) {

//Key 객체를 식별키로 사용해서 String 값을 저장하는 HashMap 객체 생성

HashMap<Key, String> hashMap = new HashMap<Key, String>();

//1.식별키 "new Key(1)" 로 "네이버"을 저장함

hashMap.put(new Key(1), "네이버");

//2.식별키 "new Key(1)" 로 "네이버"을 읽어옴

String value  = hashMap.get(new Key(1));

System.out.println(value);

Object obj = new Object();

System.out.println(obj);

System.out.println(obj.hashCode()); // 3.하지만 결과값은 null이 나옵니다.

}

}

의도한 대로 "네이버"를 읽으려면 아래와 같이 재정의한 hashCode() 메서드를 Key 클래스에 추가하면 됩니다.

public class Key {

public int number;

public Key(int number) {

this.number = number;

}

@Override

public boolean equals(Object obj) {

if(obj instanceof Key) {

Key compareKey = (Key) obj;

if(this.number == compareKey.number) {

return true;

}

return false;

}

@Override // 요 부분

public int hashCode() {

return number;

}

}

저정할 때의 new Key(1)과 읽을 때의 new Key(1)은 

사실 서로 다른 객체이지만 HashMap은 hashCode()의 리턴값이 같고 

equals() 리턴값이 true가 나오기 때문에 동등 객체로 평가합니다.

결론적으로 객체의 동등비교를 위해서는 

Object 의 equals() 메서드만 재정의하지 말고 

hashCode() 메서드도 재정의해서 논리적으로 동등 객체일 경우 

동일한 해시코드가 리턴되도록 해야합니다.

반응형