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);
}
Related
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;
}
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
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.
When overriding an equals property for one of my classes is it possible to implement it as so? The properties in question such as identifier could be String, boolean, Date, Set, or LinkedHashSet
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
if (!compareProperty(identifier, other.getIdentifier())) return false;
//Continue for all properties
}
//Compares any two objects
private boolean compareProperty(Object sourceObject, Object testObject)
{
if (sourceObject == null)
{
if (testObject != null)
return false;
}
else if(!sourceObject.equals(testObject))
{
return false;
}
return true;
}
Why or why not?
This is indeed what should be done.
I wouldn't reinvent the wheel, though. Consider using Objects.equals (in Java 7), or Objects.equal (in Guava) or an EqualsBuilder (in apache commons-lang).
I let Eclipse generate the equals method for my class and it starts with:
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (getClass() != obj.getClass())
return false;
[...]
It seems to me, a check like if (obj == null) return false; is missing. Otherwise, if a null reference is passed to equals there will be a null pointer exception in obj.getClass(). Am I wrong or is Eclipse wrong?
Perhaps you are having an old eclipse version. My eclipse generates this:
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
You are right, if Eclipse does it that way. But it doesn't. On my machine, Eclipse Indigo / Ubuntu, given this Class:
public class Foo {
private String bar;
}
Eclipse would generate the following equals() method:
#Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Foo other = (Foo) obj;
if (bar == null) {
if (other.bar != null) return false;
} else if (!bar.equals(other.bar)) return false;
return true;
}
For comparison, here's the equals() method I would write for the same class (using Guava):
#Override
public boolean equals(final Object obj) {
return obj instanceof Foo ? Objects.equal(bar, ((Foo) obj).bar) : false;
// ^--- implicit null check here
}
I use this Eclipse code template to achieve this:
${:import(com.google.common.base.Objects)}
#Override
public boolean equals(final Object obj){
return obj instanceof ${enclosing_type} ? Objects.equal(${field1:field}, ((${enclosing_type}) obj).${field1}) : false;
}
#Override
public int hashCode(){
return Objects.hashCode(${field1});
}
#Override
public String toString(){
return MoreObjects.toStringHelper(this).add("${field1}", ${field1}).toString();
}
Unfortunately, I have to keep one of these around for each cardinality of fields, so I have templates named eq1 (the above), eq2, eq3, eq4 etc. It's a small nuissance, but it's still a lot better than the monster methods generated by Eclipse.
Guava docs
Yes, passing null as obj would give a NullPointerException with that code.
You indeed need a null check. My version of Eclipse generates equals methods with a null check.
if (obj) is null, the obj.getClass() will throw an NPE
It seems to me, a check like if (obj == false) return false; is missing.
Why do you want to compare object with a Boolean value? ;-)
I suppose you though about obj == null check, and that is exactly what Eclipse generates in my case:
#Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TestGetClass other = (TestGetClass) obj;
if (id != other.id)
return false;
return true;
}
I am using 3.7 version. Anyway, you are right... actually Eclipse... too ;-)