I am comparing two objects in Java and have implemented equals and hashcode.
Though the objects are equal the comparison returns false.
I found that in the equals implementation it's printing the class of the two objects as different although they are same.
For one it prints: com.salebuild.model.TechnologyProduct
While for the other it prints: com.salebuild.model.TechnologyProduct_$$_javassist_71
So it fails in this condition in the equals method:
if (getClass() != obj.getClass())
{
return false;
}
Unable to find why it's appending this string: _$$_javassist_71
How can I overcome this? Could anyone suggest?
Use instanceof to check if both objects are of the same class.
Here is the code Eclipse offers to check object equality:
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof LdapUserDetails)) //check class here
return false;
// check fields for equality here
}
I would write something like that instead:
if (!(this instanceof TechnologyProduct))
{
return false;
}
Related
Does somebody know why this test fails? These are 2 identical objects with content inside, if I add the toString method after each Pair the test will pass. I tried to override the Equals method from the Object class but still nothing. Any help will be great, thanks
#Override
public int hashCode() {
return Objects.hash(key, value);
}
#Override
public boolean equals(Object obj) {
return super.equals(obj);
}
Pair Class Code
Error assertEquals
They are actual identical
Your problem is that your override of equals doesn't do anything - it just calls the implementation that you overrode. In other words, it has no effect.
You need to override equals in a way that does the comparison that you need. In other words, your equals needs to
check that the Object being compared to is also a Pair,
call equals for the two key fields,
call equals for the two value fields.
If any of these conditions fail, your equals should return false.
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pair<?, ?> pair = (Pair<?, ?>) o;
return key.equals(pair.key) && value.equals(pair.value);
}
This code resolved problem :)
So, I have this class:
public class Book {
private int id;
private String name;
private Something somebody;
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Book book = (Book) o;
if (id != book.id && somebody.getId() != book.somebody.getId()) return false;
return true;
}
#Override
public int hashCode() {
return id;
}
}
I would like to get all properties used in this class in equals method - in this case, I would get "id" from Book (since name is not used in equals method), and I would also get "somebody.id" since this is also used in equals method as sub object.
I need this info, so I can serialize only this properties and then during de-serialization on another machine use only that to compare equals. Otherwise it would be too cumbersome to compare full objects for equals (if I have too many sub-properties).
If you are using the Eclipse IDE, I know it has auto-complete options for equals and hashcode that will generate code including comparison of all declared fields. I am not sure if Netbeans or other IDEs have similar functionality, but would be surprised if commonly-used IDEs did not.
Also, your equals method should not compare fields of other objects but invoke equals on them:
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Book)) return false; // instanceof is fast these days
Book book = (Book) o;
if (id == book.id &&
// either ensure these are not null or use java.util.Objects.equals()
somebody.equals(book.somebody))
return true;
return false;
}
Furthermore, if your hashcode is merely using id then perhaps your equals can as well. If your object is immutable, then id is all the comparison you would need, and would be quite a bit more efficient. If that is not the case, then it is typical that the checks used in equals are reflected in your hashcode to help prevent hash collisions.
I am having a problem with overriding equals method in one class, this class has only one attribute which is a 2-dimensional array called grid. This is the constructor:
public World(int n, int m){
this.grid = new Object[n][m];
}
The equals method:
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (null == obj)
return false;
if ( !obj instanceof World)
return false;
World other = (World) obj;
if ( !Arrays.deepEquals(grid, other.grid))
return false;
return true;
}
I have already overridden the hashCode() method as well, but the problem is that doesn't matter the case, the equals is always returning true. Does anyone know what is wrong?
Be careful - you're messing with Object here.
Regardless of the actual objects you place into that array, they will all be using Object#equals for its comparison. The reason for that lies in the documentation of Arrays#deepEquals.
Two possibly null elements e1 and e2 are deeply equal if any of the following conditions hold:
e1 and e2 are both arrays of object reference types, and Arrays.deepEquals(e1, e2) would return true
e1 and e2 are arrays of the same primitive type, and the appropriate overloading of Arrays.equals(e1, e2) would return true.
e1 == e2
e1.equals(e2) would return true.
And...guess what Object#equals does:
public boolean equals(Object obj) {
return (this == obj);
}
Your arrays will only ever be equivalent if and only if they contain the exact same instances of stuff between them.
Applying stricter types around your array, such as a concrete class, may help you to get around the issue. We don't know what you're storing in that array, so I can't suggest anything concrete, but look to move away from Object.
Try this-
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof World)) {
return false;
}
World other = (World) obj;
if (!Arrays.deepEquals(this.grid, other.grid))
return false;
return true;
}
Here's how the site suggests you to write an equals() method.
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof MyType)) {
return false;
}
MyType lhs = (MyType) o;
return primitiveField == lhs.primitiveField &&
referenceField.equals(lhs.referenceField) &&
(nullableField == null ? lhs.nullableField == null
: nullableField.equals(lhs.nullableField));
}
Now, I am surely misunderstanding something, but suppose you have two MyType objects m1 and m2, and e.g. if m1.referenceField is null, this is not going to work, because when it reaches
referenceField.equals(lhs.referenceField)
it will throw a NullPointerException. Where could be my logic error?
I believe the point is that this would be a type where referenceField was guaranteed to be non-null, e.g. it's checked in the constructor.
Compare this with nullableField, where the nullity is checked as part of equals.
I need to create a subclass of HoverFrog called EOHoverFrog. Instances of EOHoverFrog differ from instances of HoverFrog in that two instances of EOHoverFrog are considered equal if their position and height are the same, regardless of their colour.
To do this, I need to write an instance method equals() for EOHoverFrog that overrides the equals() method inherited from Object. The method should accept an argument of any class. If the class of the argument is not the same as the class of the receiver, the method should simply return false, otherwise it should test the equality of the receiver and the argument.
public boolean equals(Object obj)
{
Frog.getClass().getHeight();
HeightOfFrog height = (HeightOfFrog) obj;
return (this.getPosition() == frog.getPosition());
}
please could you tell me whether I'm correct?
public boolean equals(Object obj) {
// my first (incorrect) attempt, read Carlos Heuberger's comment below
// if (!(obj instanceof EOHoverFrog))
// return false;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
// now we know obj is EOHoverFrog and non-null
// here check the equality for the position and height and return
// false if you have any differences, otherwise return true
}
that doesn't seem correct.
public boolean equals(Object obj)
{
Frog.getClass().getHeight(); // you arent assigning this to anything, and class probably
// doesn't have a getHeightMethod()
HeightOfFrog height = (HeightOfFrog) obj; // obj should be an EOHoverFrog; you should
// return false above this if obj is null or the
// wrong class
return (this.getPosition() == frog.getPosition()); // what is frog? It is not defined
// in your example
// you are not comparing heights anywhere.
}
A good way to implement an equals method is:
1) Make sure the other object passed in, obj in your case, is not null and the right class (or classes). In your case, can EOHoverFrog and HoverFrog instances be equal?
2) do your comparisons, something like
// assuming both height and position are on the base calss
var isHeightEqual = this.getHeight() == ((HoverFrog)obj).getHeight();
var isPositionEqual = this.getPosition() == ((HoverFrog)obj).getPosition();
3) now you are in position to check equality
return isHeightEqual && isPositionEqual;
First of all, read this to understand how each equals() method must behave.
Second, if you overrides the equals() method, then it's good practice to add #Override annotation before method.
To learn by examples, you can study a lot of equals() implementations here.