Menu
CoddyTech

equals()와 hashCode()

Coddy Java 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 87개 중 42번째.

Java에서 객체를 비교할 때 == 연산자는 두 참조가 같은 메모리 위치를 가리키는지 확인합니다. 객체의 실제 내용을 비교하려면 equals() 메서드를 재정의해야 합니다.

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

equals() 메서드는 표준 패턴을 따릅니다. 먼저 같은 객체인지 확인하고, 그런 다음 타입을 검증한 후, 마지막으로 관련 필드를 비교합니다.

equals()를 재정의할 때마다 hashCode()도 반드시 재정의해야 합니다. 이는 Java의 규약입니다. 서로 같은 객체는 해시 코드도 같아야 합니다. HashMap 및 HashSet과 같은 해시 기반 컬렉션은 올바르게 작동하기 위해 이 규칙에 의존합니다.

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

Objects.hash() 유틸리티 메서드는 equals()에서 사용하는 것과 동일한 필드로 해시 코드를 생성합니다. 두 Person 객체의 이름과 나이가 같으면 서로 같은 것으로 간주되어 동일한 해시 코드를 생성하며, 컬렉션에서 일관되게 동작하도록 합니다.

challenge icon

챌린지

쉬움

객체 동등성을 올바르게 구현하는 학생 기록 시스템을 만들어 봅시다. 메모리에서 같은 객체인지와 관계없이 학생 ID와 이름이 같으면 두 학생을 같은 것으로 간주하는 Student 클래스를 만들 것입니다.

코드를 두 파일로 나눕니다.

  • Student.java: 학생을 나타내는 클래스를 만들고, 비공개 필드 세 개를 선언합니다: studentId (String), name (String), gpa (double). 모든 필드를 초기화하는 생성자와 각 필드의 getter 메서드를 포함합니다.

    equals() 메서드를 재정의하여 studentId와 name이 모두 같을 때 두 Student 객체를 같은 것으로 간주하도록 합니다. 표준 패턴을 따르세요. 같은 참조인지 확인하고, null 및 타입을 확인한 다음, 해당 필드를 비교합니다.

    equals()에서 사용한 것과 같은 필드를 사용해 Objects.hash()로 hashCode() 메서드를 재정의합니다. 파일 맨 위에 java.util.Objects를 import하는 것을 잊지 마세요.

  • Main.java: 학생 객체를 비교하여 Student 클래스를 실제로 사용해 봅니다. 두 학생을 나타내는 입력 여섯 개를 받습니다. 첫 번째 학생의 ID, 이름, GPA에 이어 두 번째 학생의 ID, 이름, GPA가 입력됩니다.

    두 Student 객체를 만든 다음, 세 가지 비교를 수행하고 결과를 출력합니다.

    1. Same reference: 를 출력한 뒤 첫 번째 학생이 자기 자신과 같은지 여부를 출력합니다 (항상 true여야 합니다).
    2. Content equality: 를 출력한 뒤 첫 번째 학생과 두 번째 학생이 같은지 여부를 출력합니다 (equals 구현에 따름).
    3. Hash codes match: 를 출력한 뒤 두 학생의 해시 코드가 같은지 여부를 출력합니다.

입력은 여섯 개입니다. 첫 번째 학생의 ID (String), 첫 번째 학생의 이름 (String), 첫 번째 학생의 GPA (double), 두 번째 학생의 ID (String), 두 번째 학생의 이름 (String), 두 번째 학생의 GPA (double)가 입력됩니다.

두 학생의 ID와 이름이 일치하면 equals()가 true를 반환하고 해시 코드도 일치한다는 점에 주목하세요. 이것이 반드시 지켜야 하는 규약입니다!

직접 해보기

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 첫 번째 학생의 데이터 읽기
        String id1 = scanner.nextLine();
        String name1 = scanner.nextLine();
        double gpa1 = scanner.nextDouble();
        scanner.nextLine(); // 줄바꿈 문자 소비
        
        // 두 번째 학생의 데이터 읽기
        String id2 = scanner.nextLine();
        String name2 = scanner.nextLine();
        double gpa2 = scanner.nextDouble();
        
        // TODO: 입력 데이터를 사용하여 Student 객체 두 개 생성
        
        // TODO: "Same reference: "를 출력한 다음 student1이 자기 자신과 같은지 출력
        
        // TODO: "Content equality: "를 출력한 다음 student1과 student2가 같은지 출력
        
        // TODO: "Hash codes match: "를 출력한 다음 두 학생의 해시 코드가 같은지 출력
    }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 Java 컴파일러