Java 해싱 및 HashCode

JavaBeginner
지금 연습하기

소개

이 랩에서는 Java 의 hashCode() 메서드에 대해 배우겠습니다. 해싱 (Hashing) 은 주어진 키에 대해 고유한 값을 생성하는 데 사용되는 기술입니다. 해싱은 해시 테이블 (Hash Table) 을 구현하는 데 사용되며, 이러한 데이터 구조는 데이터를 더 빠르고 효율적으로 조회할 수 있는 방법을 제공합니다. hashCode() 메서드는 주어진 키에 대한 정수 값을 반환합니다. hashCode() 메서드를 사용하는 방법과 강력한 hashCode() 메서드를 작성하는 것의 중요성에 대해 배우겠습니다.

학생 클래스 생성

먼저, 이름, 등록 번호, GPA 와 같은 필드를 가진 Student 클래스를 생성해 보겠습니다.

class Student {
  String name;
  int regNo;
  double gpa;

  Student(String name, int regNo, double gpa) {
    this.name = name;
    this.regNo = regNo;
    this.gpa = gpa;
  }

}

equals() 메서드 사용

equals() 메서드는 두 객체가 같은지 여부를 확인하는 데 사용됩니다. 이 경우, 이름, 등록 번호 및 GPA 를 기반으로 두 개의 Student 객체를 비교합니다.

@Override
public boolean equals(Object obj) {
  if (this == obj) {
    return true;
  }
  if (obj == null || getClass() != obj.getClass()) {
    return false;
  }
  Student student = (Student) obj;
  return regNo == student.regNo &&
         Double.compare(student.gpa, gpa) == 0 &&
         Objects.equals(name, student.name);
}

hashCode() 메서드 구현

hashCode() 메서드는 주어진 키에 대한 정수 값을 반환합니다. 학생 이름의 첫 글자를 기반으로 정수를 반환하는 기본적인 hashCode() 메서드를 구현할 것입니다.

@Override
public int hashCode() {
  return (int) this.name.charAt(0) - 64;
}

hashCode() 메서드 사용 방법

이제 hashCode() 메서드를 사용하여 Student 객체에 대한 해시 코드를 생성할 수 있습니다.

Student s1 = new Student("Alice", 1, 3.7);
Student s2 = new Student("Bob", 2, 3.9);

System.out.println("s1's hash code: " + s1.hashCode());
System.out.println("s2's hash code: " + s2.hashCode());

강력한 hashCode() 메서드 구현

이전 hashCode() 메서드는 그다지 강력하지 않습니다. 이름의 첫 글자가 같은 다른 학생들에게 동일한 해시 값이 할당되기 때문입니다. 클래스의 다른 필드를 사용하여 더 강력한 hashCode() 메서드를 작성해 보겠습니다.

@Override
public int hashCode() {
  return ((int) this.name.charAt(0) - 64) * this.regNo * (int) this.gpa;
}

내장 hashCode() 메서드 사용

Student 클래스에 대한 해시 코드를 생성하기 위해 String 클래스의 내장 hashCode() 메서드를 사용할 수도 있습니다.

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

동등성 테스트

이제 equals() 메서드를 사용하여 두 Student 객체의 동등성을 테스트해 보겠습니다.

Student s1 = new Student("Alice", 1, 3.7);
Student s2 = new Student("Bob", 2, 3.9);
Student s3 = new Student("Alice", 1, 3.7);

System.out.println("s1 equals s2: " + s1.equals(s2));
System.out.println("s1 equals s3: " + s1.equals(s3));

Set 을 위한 hashCode() 구현

HashSet에서 Student 클래스를 사용할 수 있습니다. HashSet이 제대로 작동하려면 equals() 메서드와 hashCode() 메서드 둘 다 재정의해야 합니다.

Set<Student> studentSet = new HashSet<>();
studentSet.add(new Student("Alice", 1, 3.7));
studentSet.add(new Student("Bob", 2, 3.9));
studentSet.add(new Student("Alice", 1, 3.7));

System.out.println(studentSet.size()); // Output: 2

Map 을 위한 hashCode() 구현

HashMap에서도 Student 클래스를 사용할 수 있습니다. HashMap이 제대로 작동하려면 equals() 메서드와 hashCode() 메서드 둘 다 재정의해야 합니다.

Map<Student, String> studentMap = new HashMap<>();
studentMap.put(new Student("Alice", 1, 3.7), "Good");
studentMap.put(new Student("Bob", 2, 3.9), "Excellent");
studentMap.put(new Student("Alice", 1, 3.7), "Very Good");

System.out.println(studentMap.size()); // Output: 2

코드 실행

코드를 실행하려면 먼저 cd 명령어를 사용하여 코드가 저장된 디렉토리로 이동합니다. 그런 다음 javac 명령어를 사용하여 코드를 컴파일하고, java 명령어를 사용하여 코드를 실행합니다.

cd ~/project
javac HashCodeDemo.java
java HashCodeDemo

요약

이 랩에서는 주어진 키에 대한 고유한 값을 생성하는 데 사용되는 Java 의 hashCode() 메서드에 대해 배웠습니다. Student 클래스에 대한 hashCode()equals() 메서드를 구현하고 강력한 hashCode() 메서드를 작성하는 방법을 배웠습니다. 또한 HashSetHashMap에서 hashCode()equals() 메서드를 사용하는 방법을 배웠습니다.