Hashing em Java e HashCode

JavaBeginner
Pratique Agora

Introdução

Neste laboratório, aprenderemos sobre o método hashCode() em Java. Hashing (hashing) é uma técnica utilizada para gerar um valor único para uma determinada chave. O hashing é usado para implementar Hash Tables (tabelas hash), e essas estruturas de dados fornecem uma maneira mais rápida e eficiente de procurar dados. O método hashCode() retorna um valor inteiro para uma determinada chave. Aprenderemos como usar o método hashCode() e a importância de escrever um método hashCode() robusto.

Criando uma Classe Estudante

Primeiramente, vamos criar uma classe Student com campos como nome, número de matrícula e GPA (Grade Point Average - Média de Notas).

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

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

}

Usando o Método equals()

O método equals() é usado para verificar se dois objetos são iguais ou não. Neste caso, compararemos dois objetos Student com base em seu nome, número de matrícula e GPA.

@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);
}

Implementando o Método hashCode()

O método hashCode() retorna um valor inteiro para uma determinada chave. Implementaremos um método hashCode() básico que simplesmente retorna um inteiro baseado na primeira letra do nome do aluno.

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

Usando o Método hashCode()

Agora podemos usar o método hashCode() para gerar códigos hash para os objetos 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());

Implementando um Método hashCode() Robusto

O método hashCode() anterior não é muito robusto, pois diferentes alunos com a mesma primeira letra do nome receberão o mesmo valor de hash. Vamos usar os outros campos da classe para escrever um método hashCode() mais forte.

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

Usando o Método hashCode() Embutido

Também podemos usar o método hashCode() embutido para a classe String para gerar códigos hash para a classe Student.

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

Testando a Igualdade

Agora, vamos testar a igualdade de dois objetos Student usando o método equals().

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));

Implementando hashCode() para Set

Podemos usar a classe Student em um HashSet. Precisamos sobrescrever os métodos equals() e hashCode() para que o HashSet funcione corretamente.

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

Implementando hashCode() para Map

Também podemos usar a classe Student em um HashMap. Precisamos sobrescrever os métodos equals() e hashCode() para que o HashMap funcione corretamente.

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

Executando o Código

Para executar o código, primeiro, navegue até o diretório onde o código está salvo usando o comando cd. Em seguida, use o comando javac para compilar o código e o comando java para executar o código.

cd ~/project
javac HashCodeDemo.java
java HashCodeDemo

Resumo

Neste laboratório, aprendemos sobre o método hashCode() em Java, que é usado para gerar um valor único para uma determinada chave. Implementamos os métodos hashCode() e equals() para a classe Student e aprendemos como escrever um método hashCode() robusto. Também aprendemos como usar os métodos hashCode() e equals() em HashSet e HashMap.