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
andy
,x.equals(y)
should return true if and only ify.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
How to Add Local .Jar File Dependency to Build.Gradle File
What Does Servletcontext.Getrealpath("/") Mean and When Should I Use It
Scanning Java Annotations At Runtime
Byte Order Mark Screws Up File Reading in Java
Replace a Character At a Specific Index in a String
The Difference Between Classes, Objects, and Instances
How to Handle Events from Keyboard and Mouse in Full Screen Exclusive Mode in Java
How to Get the Cellrow When There Is an Itemevent in the Jcombobox Within the Cell
How to Measure Time Elapsed in Java
How to Run a Batch File from My Java Application
Difference Between Applicationcontext.Xml and Spring-Servlet.Xml in Spring Framework
In Java Streams Is Peek Really Only For Debugging
Add Leading Zeroes to Number in Java
How Does Java Garbage Collection Work With Circular References