Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Archives
Today
Total
관리 메뉴

ren+gin+eer

java equals & hashcode 본문

카테고리 없음

java equals & hashcode

윤보람 2019. 8. 21. 17:20

shallow&deep copy에 대해 테스트 코딩하면서 객체들을 비교하는데 전혀 예상치 못한 결과가 나왔다. 

 

! ArrayList는 mutable 한 객체임에도 size가 늘어날 때마다 hashcode(메모리 주소 기반)가 변경되는 것이였다. 

Document를 찾아보니 아래와 같이 연산이 되고 있어 이게 무슨 상황인가 했다.

int hashCode()
Returns the hash code value for this list. The hash code of a list is defined to be the result of the following calculation:

     int hashCode = 1;
     for (E e : list)
         hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());

 

난 단단히 오해하고 있었다. 모든 객체의 hashcode()는 객체 메모리 주소를 기반으로 hashcode를 반환한다고 착각했다. 

 

구글 검색을 한 결과

객체 비교는 동일성(Reference)과 동등성(데이터)으로 분리 할 수 있다.

 

동일성은 객체의 Reference(==)가 같은지 비교 하는 것이고

동등성은 객체가 가리키는 Reference의 데이터 자체를 비교하는 것이다. 쉽게 말해 객체의 데이터를 비교하는 것이다. 

 

Object의 equals와 hashcode는 객체의 메모리 주소 기반의 데이터로 동등성을 체크한다. 

Object 

public boolean equals(Object obj) {
        return (this == obj);	// reference 비교
}

public native int hashCode();	// native method

만약 Override 없이 두 String 객체가 같은지 비교하려면 같은 데이터를 가지고 있음에도 false가 리턴될 것이다. 

 

두 객체의 데이터가 같음을 확인 하기 위해선 Override를 해야 한다. 

String

public boolean equals(Object anObject) {
	if (this == anObject) {
		return true;
	}
  	if (anObject instanceof String) {
  		String anotherString = (String)anObject;
  		int n = value.length;
  		if (n == anotherString.value.length) {
  		char v1[] = value;
  		char v2[] = anotherString.value;
  		int i = 0;
        while (n-- != 0) {
        	if (v1[i] != v2[i])
        		return false;
        	i++;
        }
        return true;
      }
  }
	return false;
}

public int hashCode() {
	int h = hash;
	if (h == 0 && value.length > 0) {
		char val[] = value;
		for (int i = 0; i < value.length; i++) {
			h = 31 * h + val[i];
		}
		hash = h;
	}
	return h;
}

 

List 혹은 Map 같은 경우 key 혹은 데이터를 찾기 위해 equals 와 hashcode 동시에 사용한다. 

  - 두 목록의 크기가 모두 같고

  - 두 목록의 모든 해당 요소 쌍이 동일한 경우에만 true를 반환한다. 

 

그렇기 때문에 equals 와 hashcode 를 왜 동시에 Override해야 하고  둘은 보완관계임을 알 수가 있었다. 

두 메소드의 결과는 항상 동일 해야 한다.