equals() and hashCode()
Part of the Object Oriented Programming section of Coddy's Java journey — lesson 42 of 87.
When comparing objects in Java, the == operator checks if two references point to the same memory location. To compare the actual content of objects, you need to override the equals() method.
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);
}
}The equals() method follows a standard pattern: first check if it's the same object, then verify the type, and finally compare the relevant fields.
Whenever you override equals(), you must also override hashCode(). This is a contract in Java: objects that are equal must have the same hash code. Hash-based collections like HashMap and HashSet rely on this rule to function correctly.
@Override
public int hashCode() {
return Objects.hash(name, age);
}The Objects.hash() utility method generates a hash code from the same fields used in equals(). If two Person objects have the same name and age, they'll be considered equal and will produce identical hash codes, ensuring consistent behavior in collections.
Challenge
EasyLet's build a student record system that properly implements object equality. You'll create a Student class where two students are considered equal if they have the same student ID and name—regardless of whether they're the same object in memory.
You'll organize your code across two files:
Student.java: Create a class representing a student with three private fields:studentId(String),name(String), andgpa(double). Include a constructor to initialize all fields and getter methods for each field.Override the
equals()method so that two Student objects are considered equal when they have the samestudentIdAND the samename. Follow the standard pattern: check for same reference, check for null and type, then compare the relevant fields.Override the
hashCode()method usingObjects.hash()with the same fields used inequals(). Remember to importjava.util.Objectsat the top of your file.Main.java: Bring your Student class to life by comparing student objects. You'll receive six inputs representing two students: the first student's ID, name, and GPA, followed by the second student's ID, name, and GPA.Create both Student objects, then perform three comparisons and print the results:
- Print
Same reference:followed by whether the first student equals itself (should always be true) - Print
Content equality:followed by whether the first student equals the second student (based on your equals implementation) - Print
Hash codes match:followed by whether both students have the same hash code
- Print
You will receive six inputs: first student's ID (String), first student's name (String), first student's GPA (double), second student's ID (String), second student's name (String), and second student's GPA (double).
Notice how when two students have matching IDs and names, both equals() returns true AND their hash codes match—this is the contract you must maintain!
Cheat sheet
The == operator checks if two references point to the same memory location, not if objects have the same content.
To compare object content, override the equals() method following this pattern:
@Override
public boolean equals(Object obj) {
if (this == obj) return true; // Same reference
if (obj == null || getClass() != obj.getClass()) return false; // Null or different type
Person person = (Person) obj; // Cast to correct type
return age == person.age && name.equals(person.name); // Compare fields
}Whenever you override equals(), you must also override hashCode(). This is a Java contract: equal objects must have the same hash code.
@Override
public int hashCode() {
return Objects.hash(name, age);
}Use Objects.hash() with the same fields used in equals(). This ensures hash-based collections like HashMap and HashSet work correctly.
Try it yourself
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Read first student's data
String id1 = scanner.nextLine();
String name1 = scanner.nextLine();
double gpa1 = scanner.nextDouble();
scanner.nextLine(); // consume newline
// Read second student's data
String id2 = scanner.nextLine();
String name2 = scanner.nextLine();
double gpa2 = scanner.nextDouble();
// TODO: Create two Student objects using the input data
// TODO: Print "Same reference: " followed by whether student1 equals itself
// TODO: Print "Content equality: " followed by whether student1 equals student2
// TODO: Print "Hash codes match: " followed by whether both students have the same hash code
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe this KeywordMethodsFields (Attributes)Constructor MethodConstructor OverloadingRecap - Simple Calculator4Inheritance
Basic Inheritance (extends)The super KeywordMethod Overriding (@Override)Constructor ChainingThe Object ClassSingle & Multilevel InheritWhy No Multi Class InheritRecap - Employee Hierarchy7Special Methods & Object Class
toString() Methodequals() and hashCode()clone() MethodcompareTo() and ComparableComparator InterfaceRecap - Custom Sorting2Access Modifiers & Encapsulate
Access Levels OverviewGetter and Setter MethodsInformation HidingThe final KeywordRecap - Bank Account Manager5Polymorphism
Method Overloading BasicsMethod Overriding (Run-Time)Upcasting and DowncastingThe instanceof OperatorAbstract Classes and MethodsRecap - Shape Calculator8Advanced OOP Concepts
Composition vs InheritanceAggregation vs CompositionInner Nested & Anonymous ClassEnums and Enum MethodsRecords (Java 16+)Sealed Classes (Java 17+)3Class Props & Static Member
Instance vs Static VariablesStatic MethodsStatic BlocksConstants (static final)Recap - Counter & Utility6Interfaces & Abstract Classes
Introduction to InterfacesImplementing InterfacesMulti Interface ImplemenDefault & Static in InterfaceAbstract Classes vs InterfacesFunctional InterfacesRecap - Payment System