자바 hashcode

greenTea·2023년 4월 26일
0

hashcode

이펙티브 자바를 보면 equals를 재정의하면 hashcode도 재정의하라고 되어 있다. 왜 equals만 재정의하면 안되는지 아래 코드를 보며 비교해보자

code

public class Test3 {

    public static void main(String[] args) {

        Person person1 = new Person(1, "A");
        Person person2 = new Person(1, "A");

        HashSet<Person> set = new HashSet<>();

        set.add(person1);
        set.add(person2);

        for (Person person : set) {
            System.out.println("person = " + person);
        }


    }

    static class Person {
        public int age;
        public String name;

        public Person(int age, String name) {
            this.age = age;
            this.name = name;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Person person = (Person) o;
            return age == person.age && Objects.equals(name, person.name);
        }

        @Override
        public String toString() {
            return "Person{" +
                    "age=" + age +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
}

위 코드는 equals만 구현한 코드로 toString은 결과값을 보기 편하게 하기 위해 재정의해주었다.

HashSet을 선언하여 값이 같은 객체를 2개를 넣어주었다. Set은 값이 같을 경우 하나만 넣어주는 자료구조 객체이므로 우리는 1개가 나올것으로 예상 할 수 있다.

😊그러면 실행해보자!

예상과 다른 결과 값

🤔!!???

값이 2개가 찍혔다. 찍힌 값을 보면 둘다 똑같이 age=1, name='A'로 동일하다 그런데도 Set이 중복을 허용하고 있는 상황이다.

이유는 간단하다. HashSetHash값을 기준으로 중복을 판단하는데 우리는 Hash를 정의하지 않았기 때문이다.

한번 해시값을 찍어보면 알 수 있다.

hash값

System.out.println(person1.hashCode());
System.out.println(person2.hashCode());

hash값이 다른 것을 확인 할 수 있다.

그러면 이번에는 hash를 재정의해줘보자

hash 재정의

 @Override
        public int hashCode() {
            return Objects.hash(age, name);
        }

😊이제는 값이 제대로 찍히는 것을 확인 할 수 있다.

equlas만 재정의하면 위와 같이 hash를 사용하는 자료구조에서 문제가 생길 수 있기에 equals를 재정의한다면 hash도 같이 재정의해줘야 한다.(document에서도 같이 재정의 해주라고 되어있다.)

profile
greenTea입니다.

0개의 댓글