Java Hashing and HashCode

JavaJavaBeginner
Practice Now

Introduction

In this lab, we will learn about the hashCode() method in Java. Hashing is a technique used to generate a unique value for a given key. Hashing is used to implement Hash Tables and these data structures provide a faster and more efficient way to lookup data. The hashCode() method returns an integer value for a given key. We will learn how to use the hashCode() method and the importance of writing a strong hashCode() method.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("`Java`")) -.-> java/ProgrammingTechniquesGroup(["`Programming Techniques`"]) java(("`Java`")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["`Object-Oriented and Advanced Concepts`"]) java(("`Java`")) -.-> java/BasicSyntaxGroup(["`Basic Syntax`"]) java(("`Java`")) -.-> java/StringManipulationGroup(["`String Manipulation`"]) java(("`Java`")) -.-> java/SystemandDataProcessingGroup(["`System and Data Processing`"]) java/ProgrammingTechniquesGroup -.-> java/method_overriding("`Method Overriding`") java/ProgrammingTechniquesGroup -.-> java/scope("`Scope`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/annotation("`Annotation`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/generics("`Generics`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/classes_objects("`Classes/Objects`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/class_methods("`Class Methods`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/hashmap("`HashMap`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/hashset("`HashSet`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/modifiers("`Modifiers`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/oop("`OOP`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/wrapper_classes("`Wrapper Classes`") java/BasicSyntaxGroup -.-> java/identifier("`Identifier`") java/BasicSyntaxGroup -.-> java/booleans("`Booleans`") java/BasicSyntaxGroup -.-> java/comments("`Comments`") java/BasicSyntaxGroup -.-> java/data_types("`Data Types`") java/BasicSyntaxGroup -.-> java/if_else("`If...Else`") java/BasicSyntaxGroup -.-> java/operators("`Operators`") java/BasicSyntaxGroup -.-> java/output("`Output`") java/StringManipulationGroup -.-> java/strings("`Strings`") java/BasicSyntaxGroup -.-> java/type_casting("`Type Casting`") java/SystemandDataProcessingGroup -.-> java/object_methods("`Object Methods`") java/SystemandDataProcessingGroup -.-> java/string_methods("`String Methods`") java/SystemandDataProcessingGroup -.-> java/system_methods("`System Methods`") subgraph Lab Skills java/method_overriding -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/scope -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/annotation -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/generics -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/classes_objects -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/class_methods -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/hashmap -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/hashset -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/modifiers -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/oop -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/wrapper_classes -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/identifier -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/booleans -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/comments -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/data_types -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/if_else -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/operators -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/output -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/strings -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/type_casting -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/object_methods -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/string_methods -.-> lab-117411{{"`Java Hashing and HashCode`"}} java/system_methods -.-> lab-117411{{"`Java Hashing and HashCode`"}} end

Creating a Student Class

First, let's create a Student class with fields like name, registration number, and GPA.

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

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

}

Using the equals() Method

The equals() method is used to check whether two objects are equal or not. In this case, we will compare two Student objects based on their name, registration number, and 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);
}

Implementing the hashCode() Method

The hashCode() method returns an integer value for a given key. We will implement a basic hashCode() method that just returns an integer based on the first letter of the student's name.

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

Using the hashCode() Method

We can now use the hashCode() method to generate hash codes for the Student objects.

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

Implementing a Strong hashCode() Method

The previous hashCode() method is not very strong, as different students with the same first letter of their name will be assigned the same hash value. Let's use the other fields of the class to write a stronger hashCode() method.

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

Using Inbuilt hashCode() Method

We can also use the built-in hashCode() method for the String class to generate hash codes for the Student class.

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

Testing Equality

Now, let's test the equality of two Student objects using the equals() method.

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

Implementing hashCode() for Set

We can use the Student class in a HashSet. We need to override both the equals() and hashCode() methods in order for the HashSet to work properly.

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

Implementing hashCode() for Map

We can also use the Student class in a HashMap. We need to override both the equals() and hashCode() methods in order for the HashMap to work properly.

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

Running the Code

To run the code, first, navigate to the directory where the code is saved using the cd command. Then use the javac command to compile the code and the java command to run the code.

cd ~/project
javac HashCodeDemo.java
java HashCodeDemo

Summary

In this lab, we learned about the hashCode() method in Java, which is used to generate a unique value for a given key. We implemented the hashCode() and equals() methods for the Student class and learned how to write a strong hashCode() method. We also learned how to use the hashCode() and equals() methods in HashSet and HashMap.

Other Java Tutorials you may like