How to Override Equals Method in Java

How to override equals method in Java

//Written by K@stackoverflow
public class Main {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
ArrayList<Person> people = new ArrayList<Person>();
people.add(new Person("Subash Adhikari", 28));
people.add(new Person("K", 28));
people.add(new Person("StackOverflow", 4));
people.add(new Person("Subash Adhikari", 28));

for (int i = 0; i < people.size() - 1; i++) {
for (int y = i + 1; y <= people.size() - 1; y++) {
boolean check = people.get(i).equals(people.get(y));

System.out.println("-- " + people.get(i).getName() + " - VS - " + people.get(y).getName());
System.out.println(check);
}
}
}
}

//written by K@stackoverflow
public class Person {
private String name;
private int age;

public Person(String name, int age){
this.name = name;
this.age = age;
}

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}

if (obj.getClass() != this.getClass()) {
return false;
}

final Person other = (Person) obj;
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
return false;
}

if (this.age != other.age) {
return false;
}

return true;
}

@Override
public int hashCode() {
int hash = 3;
hash = 53 * hash + (this.name != null ? this.name.hashCode() : 0);
hash = 53 * hash + this.age;
return hash;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

Output:

run:

-- Subash Adhikari - VS - K false

-- Subash Adhikari - VS - StackOverflow false

-- Subash Adhikari - VS - Subash Adhikari true

-- K - VS - StackOverflow false

-- K - VS - Subash Adhikari false

-- StackOverflow - VS - Subash Adhikari false

-- BUILD SUCCESSFUL (total time: 0 seconds)

Overriding the equals() method

When overriding equals try the following. It is necessary to check for null values and improper types to prevent NPE's and casting exceptions.

  class Circle{
double radius;

@Override
public int hashCode() {
return Double.valueOf(radius).hashCode();
}

@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof Circle) {
Circle circle = (Circle)obj;
return this.radius == circle.radius;
}
return false;
}
}

The main point to remember is that the type of the equals method is Object, not your class type.

What's the correct way to override equal method in java?

The signature of equals should be :

public boolean equals(Object p)

Your public boolean equals(Person p) method doesn't override Object's equals. It overloads it.

A possible implementation :

@Override
public boolean equals(Object other)
{
if (!(other instanceof Person))
return false;
Person p = (Person) other;
return p.name.equals(this.name);
}

overriding equals method with same class strategy vs instance of strategy

There is a difference when it comes to subclasses of Person. The first implementation (Class ==) would consider a Student and a Teacher both named Alice to be different. The second (instanceof) would consider them equal.

Also, using instanceof may violate a contract of the equals() method:

•It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.

This can happen if Student overrides equals() and uses instanceOf Student. In that case, checking student.equals(person) may return false, while person.equals(student) returned true.

In general, it depends on your requirement.

Overriding equals method not working on using object as key in hashmap?

When you add new person in map personsMap.put(person,"MyCar"); first of all if key is not null the position where the element will be put is determined. It is determined by calling hashcode method for key. There are a few steps after but it doesn't matter for this example.

Since you don't override hashcode() your person and otherPerson will have different hashcode.

The same happens when you try to get value by some key. To find position where the element is, hashcode() will be invoked. But otherPerson has different hashcode and it will lead to position where is no item (null)

equals() is used when at the same position there are many elements (in list or tree structure). Then to find the right item they will be compared by equals() method

What is the need to override equals method in String class?

Not all "String in Java are interned". Try reading something from a file or console, those Strings aren't "interned", thus equals() (and also hashcode()) needs to be overriden.

Java : StackOverflow while Overriding equals method

You are recursively calling .equals in the User and Image class. Try to implement the .equals method in a different way. .equals in the User class calls .equals in the Image class and vice versa which results in a stackoverflow.

overloading or overriding equals() method

Overriding is when you implement a method that has been declared in a superclass. To qualify as an override, the signature of the override must match (within some tolerance) the signature of the method being overridden. ​

Overloading is when you have multiple methods with the same name but different signatures.

In the presence of overloads, which one is called is determined solely by the static types of the arguments at the call site. In your example, you have two overloads of equals:

boolean equals(Object o) { ... }
boolean equals(Person p) { ... }

When you call:

Person p = ...
... equals(p) ...

the overload selection process proceeds as follows:

  • Determine the static types of the arguments.
  • Determine which overloads are applicable (using arity, subtyping, conversion, etc.)
  • If more than one is applicable, determine the most specific one.
  • If two or more are equally specific, a compile-time error is issued.

Here, the argument type is Person, and both overloads are applicable (since a Person is an Object), but equals(Person) is more specific, so that one is called.

If we changed the story slightly:

Object p = new Person(...);
... equals(p) ...

Now, the static type of p is Object, so only the first overload -- equals(Object) -- is applicable. All we know is that it is an Object; that it happens to hold a Person is something that we don't know statically. (We could find it out dynamically with instanceof.)

To summarize:

  • Expressions have both a static (compile-time) and dynamic (run-time) type;
  • Overload selection is done purely on the basis of static types.

Now, you probably don't want to declare equals(Person) for the same problems you're seeing here -- it looks like an override, but really its an overload, and won't get called when you think it does.



Related Topics



Leave a reply



Submit