Equals method when dealing with inheritance and no instance variables - java

This is the way we implement equals method in classes.
Class A (Store) with area as instance variable:
#Override
public boolean equals(Object otherObject) {
if (this == otherObject) {
return true;
}
if (otherObject == null || getClass() != otherObject.getClass()) {
return false;
}
Store otherStore = (Store) otherObject;
return area == otherStore.area;
}
Class B (StoreToys) extends Class A (Store) and has no instance variables (dealing with inheritance)
How should i write equals method for this class?

If you don't introduce any new fields in StoreToys you can write the check with instanceof to verify that otherObject can be cast to Store.
#Override
public boolean equals(Object otherObject) {
if (this == otherObject) {
return true;
}
if (!(otherObject instanceof Store)) {
return false;
}
Store otherStore = (Store) otherObject;
return area == otherStore.area;
}

Related

Why equals returns false in my java code?

I do not understand why equals() returns "false" instead of "true" in my code ?
class Location {
private int x, y;
public Location(int x, int y) {
this.x = x;
this.y = y;
}
}
public class App {
public static void main(String[] args) {
Location a = new Location(1, 2); //
Location b = new Location(1, 2); // same values
System.out.println(a.equals(b)); // result : "false"
}
}
How to compare the values of two objects ?
Override the base 'equals' method with this:
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Location that = (Location) o;
return x.equals(that.x) &&
y.equals(that.y);
}
Overriding equals() method is like a routine. You can use IDE tools to generate equals() and hashcode() methods.
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Location other = (Location) obj;
if (!getEnclosingInstance().equals(other.getEnclosingInstance()))
return false;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
This method is defined in the Object class so that every Java object inherits it. By default, its implementation compares object memory addresses, so it works the same as the == operator. However, we can override this method in order to define what equality means for our objects.
You Should override override the equals() method for this class so that we can compare two Locations based on their internal details:
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Location that = (Location) o;
return x.equals(that.x) &&
y.equals(that.y);
}

Comparing Object object and Class object by overriding equals() in Java [duplicate]

This question already has answers here:
How to override equals method in Java
(11 answers)
Closed 2 years ago.
I'm trying to override the equals() method that takes an Object as input.
I have the following classes in the same package
public class Herd{
int count;
boolean exists;
In the class that is overriding the method, I am trying to compare whether the Object matches the variable in position, rank, and if they are the same Class
public class Animal{
private Herd lot;
private int rank;
public boolean equals(Object animl) {
if(this.getClass() == animl.getClass() && this.rank == animl.rank && this.lot == animl.**lot**) {
return true;
}
return false;
}
I know that to compare I will use an object that has all these parameters, however, in the Animal class itself it says
for animl.rank "rank cannot be resolved or is not a field"
for animl.lot "lot cannot be resolved or is not a field"
I tried downcasting i.e. (... == (Animal) animl.rank) but it gives me an incompatible operand types error. I also try casting the rank into an int, but it gives me the above problem.
Any help appreciated.
You need to correctly cast your animl object:
public boolean equals(Object animl) {
if(this.getClass() == ((Animal) animl).getClass() && this.rank == ((Animal) animl).rank && this.lot == ((Animal) animl).lot) {
return true;
}
return false;
}
I think it would be better if you use equals instead of =:
public boolean equals(Object animl) {
if(this.getClass() == ((Animal) animl).getClass() && this.rank.equals( ((Animal) animl).rank) && this.lot.equals( ((Animal) animl).lot)) {
return true;
}
return false;
}
Try this :
private Herd lot;
private int rank;
public boolean equals(Object animl) {
if(!(animl instanceof Animal))) {
return false;
}
Animal an = (Animal)animl;
return this.rank == an.rank && this.lot == an.lot;
}
You might need getters for those attributes. I didn't compile or test any of this.
Comparison will not work this way.
The messages:
for animl.rank "rank cannot be resolved or is not a field"
for animl.lot "lot cannot be resolved or is not a field"
are correct because there are no such properties in Object class. They only exist in your Animal class.
That said, you will need to explicitly cast the Object to Animal before doing the actual comparison. Try this:
public class Animal{
private Herd lot;
private int rank;
public boolean equals(Object animl) {
Animal animal = (Animal) animl;
if(this.getClass() == animal.getClass() && this.rank == animal.rank && this.lot == animal.lot) {
return true;
}
return false;
}
On a side note, you may need to do nested comparison for this.lot == animal.lot
Method equals in class Animal should be overridden like this:
Check for null and class equality
Cast the object to compare to Animal
Compare fields of Animal class, paying attention to using equals for the Herd
public class Animal {
// ...
#Override
public boolean equals(Object o) {
if (o == null || this.getClass() != o.getClass()) {
return false;
}
if (this == o) return true;
Animal animal = (Animal) o;
return this.rank == animal.rank &&
this.lot != null && this.lot.equals(animal.lot);
}
}
Similarly, method equals may need to be overridden in Herd:
public class Herd {
// ...
#Override
public boolean equals(Object o) {
if (o == null || this.getClass() != o.getClass()) {
return false;
}
if (this == o) return true;
Herd herd = (Herd) o;
return this.count == herd.count && this.exists == herd.exists;
}
}

indexOf() using ArrayList in java

I've a class A which is as follows:
A{
String name;
ArrayList<Bike> firstArray;
ArrayList<Cycle> secondArray;
// it's constructors and related methods are down lines.
}
and I have two instances of it named a_Obj and b_obj. I compare only the variable ,name inside object a_Obj with b_Obj using indexOf.
My question is how to call indexOf in this case and in other words how to tell the compiler that I just want to compare name of two objects regardless of ArrayLists declared inside the class A.
you can override equals() in your class
Given below is how indexOf has been implemented by default:
public int indexOf(Object o) {
ListIterator<E> it = listIterator();
if (o==null) {
while (it.hasNext())
if (it.next()==null)
return it.previousIndex();
} else {
while (it.hasNext())
if (o.equals(it.next()))
return it.previousIndex();
}
return -1;
}
By overriding the equals method in A to consider just the equality of name, you can make it happen.
Given below is the definition generated by Eclipse IDE:
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
A other = (A) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
A shorter version for the same can be as follows:
#Override
public boolean equals(Object obj) {
if (obj == null)
return false;
A other = (A) obj;
return Objects.equals(name, other.name);
}

Branch coverage in a java super class which is an abstract class

How do I solve a cobertura branch coverage issue which is being reflected in a concrete method of an abstract class.
In the below snippet the equals method of the abstract class Currency contains a part where there is a check for the variables SID and Ab which comes after the condition
if (getClass() != obj.getClass()).
This part never gets covered
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
if (getClass() != obj.getClass())
return false;
final Currency other = (Currency) obj;
if (this.getAb() == null) {
if (other.Ab() != null)
return false;
} else if (!this.getAb().equals(other.getAb()))
return false;
if (this.getSID() < 1 || (this.getSID() != other.getSID()))
return false;
return true;
}
I tried to cover these variables in the test class using the below method but it still doesn't get covered:
Test class:
Currency currency = new Currency() {
#Override
public boolean equals(Object obj) {
return super.equals(obj);
}
};
Currency currency1 = new Currency() {
#Override
public boolean equals(Object obj) {
return super.equals(obj);
}
};
currency.setAb("SE3421");
currency1.setAb("SE3421");
assertFalse(currency.equals(currency1));
assertTrue((currency1.getAb()).equals(currency.getAb()));
Any help is appreciated.
I would add a new test method, such as this.
#test
public void test_equals() {
Currency currency = new Currency() { };
assertFalse(currency.equals(new String()));
}
One other comment: you should really implement the hashCode method as well.
In hashCode() it says: If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. If you only override equals() and not hashCode() your class violates this contract

Why these two Java objects do not equals?

I was make some code and found that objects ar eno equals - it is trivial question but not understand how default equals works.
class A {
String id;
public A(String id) {
this.id = id;
}
public static void main(String args[])
{
A a = new A("1");
A b = new A("1");
System.out.println(a.id);
System.out.println(b.id);
System.out.println(a.equals(b));
}
}
Result is:
1
1
false
But I want to have a.equals(b) == true why it is false?
Your class currently extends only Object class and in Object class equals method looks like this
public boolean equals(Object obj) {
return (this == obj);
}
What you need is to override this method, for example like this
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
A other = (A) obj;
if (id == other.id)
return true;
if (id == null)
return false;
if (other.id == null)
return false;
if (!this.id.equals(other.id))
return false;
return true;
}
Also when you override equals you probably should override hashCode method, but this is not subject of your question. You can read more about it here.
If you don't override equals() on the object, you are comparing two different memory references. So override equals() to compare the id fields.
It overrides Object's equals method by default, it checks the "same object" rather than "same content". If you want to have a.equals(b) == true, you should override it:
#Override
public boolean equals (Object obj) {
if (obj instanceof A) {
A a = (A) obj;
if (id == null) {
return a.id == null;
} else {
return id.equals(a.id);
}
}
return false;
}
----- EDITED -----
you should rewrite an equals() method for your code, as you would a toString() method.

Categories

Resources