HashSet! 무엇을 기준으로 같다고 할 것인가?

devhan·2023년 8월 1일

HashSet은 2번의 검증을 한다.

  • HashSet은 이름 처럼 hash로 구성된 set이라고 보면 된다.
  • 기본적으로 hash function이 반환하는 키를 기반으로 중복을 검사한다.
  • 하지만 hash function은 같은 값을 반환할 수도 있기 때문에 혹은 임의로 hash key가 수정된 경우 때문에, 키가 같은 경우에는 obj.equals를 이용해서 한번 더 같음을 검사한다.

따라서 HashSet을 이용해서 객체의 중복을 거르고 싶다면,
hashCode 메소드와 equals 메소드를 override 해야한다.

 class Movie {
 	String title;
    
    @Override
    public int hashCode() {
    	return title.hashCode();
    }
    
    @Override
    public boolean equals(Object o) {
    	Movie aMovie = (Movie) o;
        return title.equals(aMovie.title);
    }
 }

equals 메소드를 수정할땐 hashCode도 함께!

  • 자바에서 두 object가 같다는 것은 hashCode가 같아야한다. (공식문서 링크)
  • 따라서 equals 메소드가 true를 반환하는 케이스에 대해서는 a.hashCode() == b.hashCode()가 성립해야한다.
  • 하지만 반대로 hashCode가 같다고 꼭 equals()가 true일 필요는 없다.

equals() 와 == 는 같을까?

== 는 무엇을 기준으로 같다고 이야기하는 것일까?
우선 == 는 비교되는 대상의 메모리 주소에 담긴 비트를 비교한다.

그렇다면 equal() 은 ==과 같은가?
'답은 같을 수도 있고, 아닐수도 있다.' 이다.

기본적으로 최초에 구현된 equals 메소드는 ==와 동일하게 동작한다. 하지만 equals 메소드는 Override 될 수 있기 때문에 항상 같다고 할 수 없다.
(실제로 String, Integer 같은 객체에는 다르게 동작하는 것을 알 수 있다.)

class Test {
	...
    
   	public void test() {
    	String str1 = "hihi";
        String str2 = "hihi";
        
        System.out.println(str1.hashCode());
		System.out.println(str2.hashCode());
		System.out.println(str1 == str2); // true
    }
}
profile
한번에 한가지씩

0개의 댓글