hashcode() : int

satic·2025년 3월 25일

hashCode() : int

1. 개요

hashCode() 메서드는 자바에서 객체의 해시 코드(Hash Code)를 반환하는 메서드입니다.

  • 반환값: int (객체를 식별하는 정수 값)
  • 역할: HashMap, HashSet 등의 컬렉션에서 객체를 빠르게 검색하고 비교하는 데 사용됨
public int hashCode()

기본적으로 Object 클래스의 hashCode()는 객체의 메모리 주소를 기반으로 해시 값을 생성합니다.


2. 기본 동작 (Object의 hashCode)

Object 클래스에서 제공하는 기본 hashCode()객체의 메모리 주소를 기반으로 한 해시 값을 반환합니다.

class Sample {}

public class Main {
    public static void main(String[] args) {
        Sample s1 = new Sample();
        Sample s2 = new Sample();

        System.out.println(s1.hashCode()); // 예: 366712642
        System.out.println(s2.hashCode()); // 예: 1829164700 (다른 값)
    }
}

🔹 객체가 다르면 일반적으로 다른 해시 값을 가집니다.
🔹 같은 객체라도 실행할 때마다 해시 값이 다를 수 있습니다.


3. hashCode()와 equals()의 관계

  • hashCode()equals()함께 오버라이딩해야 합니다.
  • 같은 객체라고 판단하는 경우(equals()가 true인 경우), hashCode() 값도 동일해야 합니다.

올바른 hashCode() 오버라이딩 예제

import java.util.Objects;

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = 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);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age); // name과 age를 기반으로 해시 값 생성
    }
}

public class Main {
    public static void main(String[] args) {
        Person p1 = new Person("홍길동", 30);
        Person p2 = new Person("홍길동", 30);

        System.out.println(p1.equals(p2)); // true (값이 동일)
        System.out.println(p1.hashCode() == p2.hashCode()); // true (같은 해시 값)
    }
}

🔹 Objects.hash(name, age)를 사용하면 간편하게 해시 코드를 생성할 수 있습니다.
🔹 equals()true인 경우 hashCode() 값도 동일해야 합니다.


4. hashCode()의 역할 (HashMap, HashSet에서 사용)

자바 컬렉션에서 hashCode()는 중요한 역할을 합니다.

HashSet에서 hashCode() 사용 예시

import java.util.HashSet;
import java.util.Objects;

class Car {
    private String model;

    public Car(String model) {
        this.model = model;
    }

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

        Car car = (Car) obj;
        return Objects.equals(model, car.model);
    }

    @Override
    public int hashCode() {
        return Objects.hash(model);
    }
}

public class Main {
    public static void main(String[] args) {
        HashSet<Car> carSet = new HashSet<>();

        Car c1 = new Car("Tesla Model S");
        Car c2 = new Car("Tesla Model S");

        carSet.add(c1);
        carSet.add(c2); // 중복된 객체로 간주되어 추가되지 않음

        System.out.println(carSet.size()); // 1 (같은 모델이므로 중복 제거됨)
    }
}

🔹 hashCode()를 올바르게 오버라이딩하면 HashSet이 중복을 제거할 수 있습니다.
🔹 equals()true이면 hashCode() 값도 같아야 하므로, 같은 객체로 인식됩니다.


5. hashCode() 충돌 방지

hashCode()는 서로 다른 객체에 대해 동일한 해시 값을 반환할 수도 있습니다. 이를 해시 충돌(Hash Collision) 이라고 합니다.

  • 해시 충돌을 줄이기 위해 고유하고 균등하게 분포하는 해시 값을 생성하는 것이 중요합니다.

hashCode 충돌 방지 방법

  1. 프라임 숫자(31, 37, 53 등)를 사용하여 해시 코드 생성
@Override
public int hashCode() {
    int result = 17; // 초기값은 소수
    result = 31 * result + name.hashCode();
    result = 31 * result + age;
    return result;
}
  1. Objects.hash() 활용 (간결하고 안전)
@Override
public int hashCode() {
    return Objects.hash(name, age);
}
  1. Apache Commons Lang의 HashCodeBuilder 사용
import org.apache.commons.lang3.builder.HashCodeBuilder;

@Override
public int hashCode() {
    return new HashCodeBuilder(17, 37) // 초기값과 곱할 값을 설정
            .append(name)
            .append(age)
            .toHashCode();
}

정리

메서드역할
equals()객체의 내용(필드 값) 이 같은지 비교
hashCode()객체의 고유한 해시 코드를 반환
hashCode()equals()함께 오버라이딩하여 HashSet, HashMap에서 정상 동작 보장

profile
95.06.09

0개의 댓글