JonnyNuggets
JonnyNuggets

Reputation: 3

Incorrectly overriding the equals method for hashSets in Java

I have the following code:

public class Trooper {
private String name;
private boolean mustached;
public Trooper(String name, boolean hasMustache) {
    this.name = name; this.mustached = hasMustache;
}
public String getName() { return name; }
public boolean hasMustache() { return mustached; }
public boolean equals(Trooper other) {
    if (this == other) return true;
    if (null == other || !(other instanceof Trooper)) return false;
    Trooper that = (Trooper) other;
    return this.name.equals(that.name) && this.mustached == that.mustached;
}
public int hashCode() { return 1; }
}

Then the following is run:

ArrayList<Trooper> troopers = new ArrayList<>();
troopers.add(new Trooper("Farva", true));
troopers.add(new Trooper("Farva", true));
troopers.add(new Trooper("Rabbit", false));
troopers.add(new Trooper("Mac", true));
Set<Trooper> trooperSet = new HashSet<>(troopers);

Why does the following code return false?

trooperSet.contains(new Trooper("Mac", true));

I understand how hashCode and equals are used in a hashSet when the contains method is invoked. The only reason that I can guess that it returns false instead of true is that the equals method hasn't been properly overridden. If this is the reason the previous statement returns false, why is that the case?

Upvotes: 0

Views: 341

Answers (2)

DavidW
DavidW

Reputation: 1421

You're overloading the equals() method, not overriding it.

Object.equals() is defined as: public boolean equals(Object obj) by specifying your argument as type Trooper you've defined a new method signature.

Using the @Override annotation really helps catch errors like this; the annotation will warn you you're not actually overriding anything. (The static inspections in a good IDE like IntelliJ will also catch this, but that's not everyone's cuppa.)

Upvotes: 0

arshajii
arshajii

Reputation: 129537

You're overloading the equals() method, not overriding it. Here's the difference. The correct signature for equals() is:

public boolean equals(Object other) {
    ...
}

Your current equals() is never used by the HashSet. Instead, Object#equals() is being used, hence the result.

By the way, including an @Override tag can help spot these mistakes.

Upvotes: 2

Related Questions