hashCode()가 뭐지?

Sandro·2022년 11월 24일
0

java

목록 보기
2/3
post-thumbnail

이전에 equals에 대해 알아봤다. equals와 짝꿍인 hashCode를 알아보자.

종류과 숫자를 맴버 변수로 갖는 카드 클래스가 있다. equals는 구현해 뒀다.

class Card {
    private String kind;
    private int number;

	@Override
    public boolean equals(Object o) {
    	// 종류와 숫자가 같다면 true
    }
}

같은 값을 갖는 객체를 2개 만들었다.

중복 허용하지 않는 HashSet에 Card 객체를 넣었다. 두 객체의 값이 같고 equals 메서드도 구현해뒀기 때문에 set의 size는 1로 예상할 수 있다.

확인해보니 2개의 객체가 그대로 들어있다. 제대로 중복 제거가 되지 않았다. 왜 그럴까?

*public* static void main(String[] args) {
    Card card1 = new Card("spade", 1);
    Card card2 = new Card("spade", 1);

    HashSet<Card> cards = new HashSet<>();
    cards.add(card1);
    cards.add(card2);

    System.out.println(cards.size());  // 2
}

HashSet

해싱기법을 사용하는 자료구조 (HashMap, HashSet 등)는 객체를 해시코드로 변환해서 같은 객체인지 판단한다.
더 알아보기 : 해시테이블

💡 해시코드란?
  • 해시함수에 데이터를 넣어서 반환되는 정수 값이다.
  • 데이터를 비교하기 위해 사용한다. 해시코드가 같으면 같은 데이터, 다르면 다른 데이터로 판단한다.

중복제거가 되지 않는 이유는 두 객체의 해시코드가 다르기 때문이라고 생각할 수 있다.

객체들의 해시코드 찍어본다.

System.out.println(card1.hashCode());  // 883049899
System.out.println(card2.hashCode());  // 664223387
// 주소 값으로 해시코드를 생성하기 때문에 값이 다르다.

맞았다. 두 값이 다르다. 어떻게 해결할까?

HashCode()

  • Object 클래스에 정의된 메서드
  • 객체의 데이터를 이용해서 해시코드를 생성한다. Object에 정의된 hashCode()는 객체의 주소값으로 해시코드를 생성한다. 따라서 주소가 다르면 다른 해시코드가 반환된다.

해시코드를 오버라이드 해서 주소가 다르더라도 값이 같다면 두 객체를 같은 객체로 판단하게 만들어야 한다.

Objects.hash(Object… values)를 사용한다. 종류와 숫자를 조합해서 해시코드를 생성한다.

@Override
public int hashCode() {
    return Objects.hash(kind, number);
}

결과 확인

System.out.println(card1.hashCode());  // -896190659
System.out.println(card2.hashCode());  // -896190659

System.out.println(cards.size());  // 1
// hashCode() 오버라이드 후 결과 확인

성공!

정리

  • HasehMap이나 HashSet을 사용할 때는 꼭 equals, hashCode를 재정의하자!
  • equals() 오버라이드할 때 hashCode()도 오버라이드 하자.
profile
안녕하세요!

0개의 댓글