hashcode메소드를 오버라이딩하는 이유

조회수 3867회

자바에서 hashcode메소드를 오버라이딩하는 이유는 뭔가요?

1 답변

  • 좋아요

    0

    싫어요
    채택 취소하기

    hashcode 메소드의 오버라이딩이 필요한 예를 들어서 설명해드리겠습니다. 우선 두 객체가 동일하다면 두 객체의 각 hashCode의 값은 동일하게 나와야합니다.

    public class Student {
        private int student_id;
        private String name;
        private String major;
    
        public Student(int id, String n, String m){
            student_id = id;
            name = n;
            major = m;
        }
    
        public int getStudent_id() {
            return student_id;
        }
        public void setStudent_id(int student_id) {
            this.student_id = student_id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getMajor() {
            return major;
        }
        public void setMajor(String major) {
            this.major = major;
        }
    }
    

    이렇게 Student클래스가 있을때 이 클래스를 HashMap과 같이 쓴다고 하면

    Map<Student,String> m = new HashMap<Student,String>();
    m.put(new Student(20113263,"김성국","Computer Science"),"Sean");
    

    이런식으로 입력했을때 m.get(new Student(20113263,"김성국","Computer Science"))를 호출하면 "Sean"이 반환 될것 같지만 실제로는 null을 반환 합니다. 이렇게 되는 이유는 hashcode를 오버라이딩 하지 않아서 두 인스턴스가 서로 다른 해시 코드 값을 같게 되어서 그렇습니다. 따라서 get메소드로 검색한 인스턴스는 put메소드에서 저장한 인스턴스의 것과 다른 버킷에서 Student를 찾게되는 것입니다. 이런 문제는 hashCode를 오버라이딩해주면 간단히 해결됩니다.

    그렇다면 hashCode는 어떻게 오버라이딩해주어야 좋을까요?

    최악의 hashCode는 @Override public int hashCode(){return 42;} 이런 형태입니다. 이 형태는 동일한 객체들이 같은 해쉬 값을 갖게되므로 어떻게 보면 적법하다고도 할수 있지만 모든 객체가 다 똑같은 해쉬 값을 갖는 최악의 형태입니다. 이렇게 되면 모든 객체는 같은 버킷에 위치하고 새로 넣을때마다 계속 충돌이 발생해 링크드 리스트로 버킷을 연결해서 선형 구조가 되어 탐색과 삽입삭제가 엄청나게 느려지는 결과를 초래합니다.

    좋은 hashCode메소드는 서로 다른 객체들을 가능한 해쉬 값에서 고르게 분포시켜주는게 좋습니다.

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)