JAVA

==, equals(), hashcode() 비교

아무 생각 없이보면 객체가 동일한지 비교한다고 생각할 수 있지만 

자세히 보면 다르게 동작하는 것을 알수 있다.

== 연산자

String str1 = "hello";
String str2 = "hello";
System.out.println(str1 == str2);//true

String str3 = new String("hello");
String str4 = new String("hello");
String str5 = str4;
System.out.println(str3 == str4);//false
System.out.println(str4 == str5);//true

 

앞선 상수 풀 글을 읽으셨다면 str1과 str2는 동일한 객체의 주소값을 참조하고 있다는 것을 알 수 있습니다.

str3과 str4는 다른 객체를 str5와 str4는 같은 객체의 주소값을 참조하고 있습니다.

 

위의 결과를 보면 == 비교는 동일한 객체의 주소값을 참조하고 있을 때 동일하다라고 하는 것을 알 수 있습니다.

 

equals()

    public boolean equals(Object obj) {
        return (this == obj);
    }

최상위 객체인 Object에 구현된 equals() 메서드는 == 비교를 사용한다.

String s1 = new String("Test");
String s2 = new String("Test");

System.out.println(s1 == s2);			// false
System.out.println(s1.equals(s2));		// true;

그렇다면 이상하다 위의 예시를 보면 s1, s2는 서로 다른 객체를 참조하고 있는데 equals가 true를 반환한다. 

이는 String 클래스에서 equals 메소드를 오버라이드하여 문자를 비교하는 코드를 추가했기 때문이다. 

equals는 객체가 오버라이딩을 통해서 내용을 비교하도록 구현할수 있다.

 

hashcode()

equals와 마찬가지로 Object에 속하여 기본 구현은 객체의 주소를 기준으로 객체를 식별할 수 있는 정수 코드를 리턴하는 메소드이다. 

HashMap, HashSet, Hashtable과 같은 프레임워크에서 논리적 동등 여부를 체크하기 위해서 오버라이딩 한다.

 

public V get(Object key) {
	Node<K,V> e;
    return (e = getNode(hash(key), key)) == null ? null : e.value;
}

public V put(K key, V value) {
	return putVal(hash(key), key, value, false, true);
}
    
static final int hash(Object key) {
	int h;
	return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

HashMap의 get, put, hash 메서드로 저장 및 조회할 때 키값을 해쉬해서 저장하기 하게되며 특정 객체를 기준으로 조회를 할때 hashcode가 오버라이딩 되어 있지 않다면 모든 객체를 다른 객체로 인식하게 됩니다.

 

equals()와 hascode의 관계

equals(Object)메소드가 true이면 두 객체의 hashCode 값은 같아야 한다.
equals(Object)메소드가 false이면 두 객체의 hashCode가 꼭 다를 필요는 없다.
하지만 서로 다른 hashCode 값이 나오면 해시 테이블(hash table)의 성능이 향상될 수 있다는 점은 이해하고 있어야 한다.