Back_End/Java

Java에서 equals()와 hashCode() 메서드 오버라이딩

10Biliion 2024. 12. 6. 14:52

 

 

equals()와 hashCode()란 무엇인가? 🤔

  • equals() 메서드: 두 객체가 논리적으로 동등한지 비교합니다. 기본적으로 Object 클래스에서 제공하는 equals()는 두 객체의 참조값(메모리 주소)을 비교합니다.
  • hashCode() 메서드: 객체를 식별하는 정수 값을 반환합니다. 이 값은 해시 기반 컬렉션(예: HashMap, HashSet)에서 객체를 저장하고 검색하는 데 사용됩니다.

두 메서드의 관계

equals()hashCode()는 다음과 같은 규칙에 따라 동작해야 합니다:

  1. equals()가 true를 반환하는 두 객체는 동일한 hashCode() 값을 가져야 합니다.
  2. hashCode() 값이 같은 객체가 반드시 equals()에서 true를 반환할 필요는 없습니다.

이 규칙을 지키지 않으면 HashMap이나 HashSet과 같은 컬렉션에서 객체를 올바르게 처리하지 못합니다.


왜 두 메서드를 함께 오버라이딩해야 할까?

1. hashCode()를 오버라이딩하지 않은 경우의 문제

import java.util.HashSet;

class Person {
    private String name;

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

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

public class Main {
    public static void main(String[] args) {
        Person p1 = new Person("Alice");
        Person p2 = new Person("Alice");

        HashSet<Person> set = new HashSet<>();
        set.add(p1);

        System.out.println(set.contains(p2)); // false
    }
}

문제 설명

  • equals() 메서드를 오버라이딩했으므로 p1p2는 논리적으로 동등합니다.
  • 그러나 hashCode()를 오버라이딩하지 않았기 때문에 HashSetp2p1과 동일한 객체로 인식하지 못합니다.

2. equals()를 오버라이딩하지 않은 경우의 문제

import java.util.HashSet;

class Person {
    private String name;

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

    @Override
    public int hashCode() {
        return name.hashCode();
    }
}

public class Main {
    public static void main(String[] args) {
        Person p1 = new Person("Alice");
        Person p2 = new Person("Alice");

        HashSet<Person> set = new HashSet<>();
        set.add(p1);

        System.out.println(set.contains(p2)); // false
    }
}

문제 설명

  • hashCode()는 오버라이딩했으나 equals()를 오버라이딩하지 않았기 때문에 HashSet은 두 객체가 다르다고 판단합니다.

올바른 오버라이딩 예제

import java.util.HashSet;

class Person {
    private String name;

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

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

    @Override
    public int hashCode() {
        return name.hashCode();
    }
}

public class Main {
    public static void main(String[] args) {
        Person p1 = new Person("Alice");
        Person p2 = new Person("Alice");

        HashSet<Person> set = new HashSet<>();
        set.add(p1);

        System.out.println(set.contains(p2)); // true
    }
}

결과 설명

  • equals()hashCode()를 모두 오버라이딩했기 때문에 HashSetp1p2를 동일한 객체로 인식합니다.

  1. equals()hashCode()는 항상 함께 오버라이딩해야 합니다.
  2. equals()는 객체의 논리적 동등성을 정의하고, hashCode()는 해시 기반 컬렉션의 효율적인 동작을 보장합니다.

 

 

'Back_End > Java' 카테고리의 다른 글

추상 클래스와 인터페이스  (1) 2024.12.11
객체지향 설계의 5원칙 (SOLID)  (0) 2024.12.11
ORM(Object-Relational Mapping) 이란?  (2) 2024.12.06
자바(Java)의 장단점  (3) 2024.12.05
자바(Java) Enum 이란?  (1) 2024.12.05