C7: Overriding equals (and hashCode)

CPSC 210

Learning Goals

  • Understand why we sometimes need to override equals (and hashCode)
  • Understand a given implementation of equals
  • Learn how to override equals/hashCode (or use the IDE to help us)
  • Understand the instanceof operator in Java

Handling Duplicate Objects

  • At the top of every class hierarchy is the Object class
  • Among others, this class defines the following methods
    • boolean equals(Object other)
    • int hashCode()
  • These are used, for example, by the contains methods in Java collections
List<Instructor> instructors = new ArrayList<>();
instructors.add(new Instructor("Felix"));

Instructor instructor = new Instructor("Felix");
instructors.contains(instructor);

Handling Duplicate Objects (2)

  • What we need to know about in this course:
    • ​Object class implements a.equals(b) as a == b
    • Method can be overridden to change this behavior
  • We can let IntelliJ help us generate these methods:
    • Code > Generate > equals() and hashCode()

Let's ask the docs!

Lecture Ticket Review
Live Coding!!!

public class RecipeBook {

  private String name;
  private Map<String, List<String>> recipes;

  public RecipeBook(String name){
    this.name = name;
    this.recipes = new HashMap<>();
  }

  // REQUIRES: recipeName is not already in recipes
  // MODIFIES: this
  // EFFECTS: adds recipeName to recipes, and assigns an empty list of ingredients
  public void addNewRecipe(String recipeName){
    List<String> ingredients = new ArrayList<>();
    //BLANK 1
  }

  // REQUIRES: recipeName is in recipes
  // MODIFIES: this
  // EFFECTS: adds ingredient to recipeName's list of ingredients
  public void addToRecipe(String recipeName, String ingredient){
    List<String> ingredients = recipes.get(recipeName);
    //BLANK 2
  }

  public void printRecipes(){
    System.out.println(this.recipes);
  }
}

Auto-generated equals method

@Override
public boolean equals(Object o) {
  boolean equal = false;
  if (o instanceof Instructor) {
    Instructor that = (Instructor) o;
    equal = this.name.equals(that.name);
  }
  return equal;
}
  • Let's assume we have a class Instructor with a field name and:
    • we want to consider two instructor objects equal if they have the same name

we can write a similar implementation using the instanceof operator

@Override
public boolean equals(Object o) {
  if (this == o) return true;
  if (o == null || getClass() != o.getClass()) return false;
  Instructor that = (Instructor) o;
  return Objects.equals(name, that.name);
}

auto-generated equals

Java instanceof operator

  • Example: a class Rectangle extends another class Shape
    • If we have an object of type Shape named shape, then shape instanceof Shape will evaluate to true
    • But: shape instanceof Rectangle will evaluate to false
    • If we have an object of type Rectangle named rectangle, then rectangle instanceof Shape will evaluate to true
@Override
public boolean equals(Object o) {
  boolean equal = false;
  if (o instanceof Instructor) {
    Instructor that = (Instructor) o;
    equal = this.name.equals(that.name);
  }
  return equal;
}

instanceof: Checks whether the object on the left is the same type or a subtype of the object on the right

Lecture Lab

C7: Overriding equals and hashCode

The End - Thank You!

CPSC 210 - C7: Overriding equals and hashCode

By Felix Grund

CPSC 210 - C7: Overriding equals and hashCode

  • 1,311