What is wrong with my equals method? - java

I am writing a Complex number class and my equals method doesn't seem to be working. I'm supposed to be checking to see if two ComplexNum objects are equal to each other and I am always coming across a logic error that always returns false.
public boolean equals(Object x) {
ComplexNum real = (ComplexNum) x;
if (x == null)
return false;
if (x instanceof ComplexNum && this.imag == (real.real)) {
return true;
} else
return false;
}
This is my demo class
ComplexNum y = new ComplexNum(3.0,15.0);
ComplexNum z = new ComplexNum(3.0,15.0);
System.out.println(y.equals(z));
false < -- my output is false no matter what the values are

You're not performing a like-for-like comparison on the real and imaginary components of your complex number.
This would be my implementation:
public boolean equals(Object o) {
if (o instanceof ComplexNum) {
ComplexNum other = (ComplexNum)o;
return (this.real == other.real) && (this.imag == other.imag);
} else {
return false;
}
}
For those arguing that floating point comparison should never use precise tests, IMHO that should be in another method. Java requires that objects that are .equal() have the same .hashCode(), and that would be very hard to arrange with an epsilon comparison.
Because of the above, you will need this, too (other implementations are possible, and the below assumes that your components are double)
int hashCode() {
return Double(this.real).hashCode() ^ Double(this.imag).hashCode();
}
NB: A test for o == null is not necessary in .equals(), because null is not an instanceof ComplexNum.
EDIT for completely strict conformance with the way that .equals() works on Float or Double types (particularly for NaN values) you might want to use this line instead which replaces == with a per-component application of .equals()
return Double(this.real).equals(other.real) &&
Double(this.imag).equals(other.imag);

Related

How to override equals without increasing cyclomatic complexity?

I was recently overriding some equals methods in domain objects of my recent Java project. As we are using Sonar to calculate our code metrics, I immediately saw the cyclomatic complexity of these classes increasing above a threshold.
I'm wondering if there is a clever way, pattern or option at all to keep this metric low although having a little more complex equals method.
EDIT: Here is one of my examples that I have, nothing really specific I would say, just so that we know what we are talking about.
#Override
public boolean equals(Object o) {
if (o instanceof MyKey) {
MyKey other = (MyKey) o;
if (this.foo.longValue() == other.getFoo().longValue() &&
this.bar.equalsIgnoreCase(other.getBar()) &&
this.foobar.shortValue() == other.getFoobar().longValue()){
return true;
}
}
return false;
}
#Override
public int hashCode() {
int hash = 3;
hash = 53 * hash + foo.hashCode();
hash = 53 * hash + bar.hashCode();
hash = 53 * hash + foobar.hashCode();
return hash;
}
You could use Apache's EqualsBuilder:
public boolean equals(Object obj) {
if (obj == null) { return false; }
if (obj == this) { return true; }
if (obj.getClass() != getClass()) {
return false;
}
MyClass rhs = (MyClass) obj;
return new EqualsBuilder()
.appendSuper(super.equals(obj))
.append(field1, rhs.field1)
.append(field2, rhs.field2)
.append(field3, rhs.field3)
.isEquals();
}
You didn't but you should always check for nulls. foo could be null, resulting in a NullPointerException.
this.foo.longValue() == other.foo.longValue()
Luckily Objects utility class saves you from a lot of problems as it automatically checks for nulls.
#Override
public boolean equals(Object object) {
if (object == null)
return false;
if (!(object instanceof MyObject))
return false;
MyObject other = (MyObject) object;
//#formatter:off
return Objects.equals(getX(), other.getX()) &&
Objects.equals(getY(), other.getY()) &&
Objects.equals(getZ(), other.getZ()));
//#formatter:on
}
#Override
public int hashCode() {
return Objects.hashCode(getX(), getY(), getZ());
}
If the fields to check are a lot you can optionally add this at the beginning of the equals method.
if (object == this)
return true;
In theory it can save some computation in some edge case.
The only thing that really helps, in my opinion, is good indentation. I always wrap those line between a pair of //#formatter:off and //#formatter:on. It's boilerplate code, anyway: very easy to write, very easy to make mistakes.
In your case, though, you're checking equality using equalsIgnoreCase. It's a pity Objects doesn't have such a method. You can build your own pretty easily.
public final class Strings {
public static boolean equalsIgnoreCase(String a, String b) {
return a == null ? b == null : a.equalsIgnoreCase(b);
}
private Strings() {
}
}
And use it like this
return Objects.equals (getX(), other.getX()) &&
Strings.equalsIgnoreCase (getY(), other.getY()) &&
Objects.equals (getZ(), other.getZ()));

How do I specify both objects when overriding equals method?

I'm doing an assignment that asks me to override the equals method of a house class.
The instructions are as follows:
Two houses are equal when their building areas are equal and their pool status is the same
Until now, this is what I've wrote:
#Override
public boolean equals(Object other) {
if (other instanceof House) {
House otherHouse = (House) other;
return otherHouse.calcBuildingArea() == ???
&& otherHouse.mPool == ???
} else {
return false;
}
}
Now I don't know what to write after the == signs. I don't know how to specify the object that calls the method.
If you call a method without specifying an object, the method will get called on the current object. So you can write
return otherHouse.calcBuildingArea() == calcBuildingArea()
&& otherHouse.mPool == mPool;
or if you want to make it nice and clear and explicit, you can write
return otherHouse.calcBuildingArea() == this.calcBuildingArea()
&& otherHouse.mPool == this.mPool;
Note also that this assumes that mPool is of a primitive type or an enum type. If it's a reference type, such as String, you may need to invoke its equals method like
return otherHouse.calcBuildingArea() == calcBuildingArea()
&& otherHouse.mPool.equals(mPool);
or even the more null-friendly
return otherHouse.calcBuildingArea() == calcBuildingArea()
&& Objects.equals(otherHouse.mPool, mPool);
How about this?
return otherHouse.calcBuildingArea() == this.calcBuildingArea()
&& otherHouse.mPool == this.mPool

How do I compare the "state" of two objects of the same type?

I'm supposed to create my own equals() method which overrides the equals(method) of the parent class. This method accepts a Counter object as its argument. In the code below, I want an easy way to determine if the Counter object argument equals the current instance of the Counter class, if that makes sense. I have achieved this in the code below by comparing the fields of each object one by one, but I want a simpler way to do it. Something that looks like this would be nice: "result = (otherCounter == new Counter(min,max) ? true : false);", but I know that's not right and it gets an error. How do I compare the equality of the variables in the two Counter objects, so that c1.equals(c2) will be false if Counter objects c1 and c2 are different?
public boolean equals(Object otherObject)
{
boolean result = true;
if (otherObject instanceof Counter)
{
Counter otherCounter = (Counter)otherObject;
result = (otherCounter.min == this.min) &&
(otherCounter.max == this.max) &&
(otherCounter.currentCount == this.currentCount) &&
(otherCounter.rolloverOccurrence == this.rolloverOccurrence) ? true : false;
}
return result;
}
Operator overloading is not possible in Java.
And to compare two object are equal or not you should use .equals() method no matter what.
Ex: obj1.equals(obj2)
It is because sometimes Java API (ex: Collections) will internally call equals method to sort the collection. So there is no simple way to compare but to use equals()
Your method is just fine like this except for the other answers you got here that state that there is not overloading of operators in Java, the thing with the result = true instead of false and commenting you remember to override hashCode if you didn't already do. Let me give you one more advise. The method can be written in some more compact way:
public boolean equals(Object obj) {
if (!(obj instanceof Counter)) {
return false;
}
Counter other = (Counter) obj;
return other.min == this.min && other.max == this.max &&
other.currentCount == this.currentCount &&
other.rolloverOccurrence == this.rolloverOccurrence;
}

public boolean equals(Object other)

This is for a Fraction program. I have private ints num and den, Fraction, and FractionInterface - the standard homework problem. I have done pretty much everything and now have been stuck for a few hours on the equals method. Since other is an Object, I can't equate it to Fraction. Here's what I have:
public boolean equals(Object other){
if (other == this){
return true;
} else {
return false;
}
}
This compiles but it gives incorrect results:
1/2 eq 1/2 = true
1/2 eq 1/2 = true
1/2 eq 1/2 = false
1/2 eq 1/2 = false
If I try other == Fraction, it doesn't compile. Thanks for any help!
You can test if other is an instance of FractionInterface and use a cast:
public boolean equals(Object other){
if (other == this){
return true;
} else if (other instanceof FractionInterface) {
FractionInterface fOther = (FractionInterface) other;
// compare numerator and denominator...
} else {
return false;
}
}
Note that instanceof will be false if other == null, so there's no need for a separate null check.
Try this out:
First, cast the other object
Fraction otherFraction = (Fraction) other;
Then, determine the condition that the two fractions are equivalent.
This will include some logic involving the comparing of numerator and denominators (expect to use getNum() and getDen() for the otherFraction.
You should check whether the argument is an instance of your class and return false if it isn't and cast it to your class and compare according to your needs if it is. It's common to write equals() method like this:
public boolean equals(Object obj) {
if (!(obj instanceof Fraction)) {
return false;
}
Fraction that = (Fraction) obj;
... // Your algorithm to compare two fractions: this and that.
}
You should make sure that your algorithm for comparing two fractions meets all the requirements described in equals() documentation.
You need to test if the object has the Fraction class, and if so, cast it to a Fraction:
if (other.getClass() != Fraction.class) {
return false;
}
Fraction otherFraction = (Fraction) other;
// compare the fields of this and otherFraction
Before doing this, make sure to also test for null.
You are comparing that the two objects references refer to the same object.
You will need to check that the other is of type Fraction and then type cast it to a Fraction. You are then about to compare the two parts of the Fraction.
I think you're close, but you're missing a few key concepts. This is because your as is won't work in all situations. Try this for example using your existing code...
Fraction a = // this is however you're making a fraction object...
Fraction b = // do EXACT same thing here that you did for a
// And then, this will illustrate what is wrong with your program...
if(a.equals(b)) {
System.out.println("This won't print");
} else {
System.out.println("This will print because your method just checks for reference");
}
So here are the basics you need to understand:
Difference between == and equals
Comparing type as opposed to reference or value
Avoiding casting by putting your "equals" method in the proper place
First off...
public boolean equals(Object other){
if (other == this){
return true;
} else {
return false;
}
}
You're missing the point of the "equals" method in Java. == is used to compare references while this.equals(foo) is used to put the logic for comparing objects in a localized place.
The other concept you're missing is how instanceof should be used. When you ask this...
If I try other == Fraction, it doesn't compile.
This is because you're looking to compare the type of the object. To do this, you would simply do...
if(other instanceOf Fraction) {
// do stuff...
}
All of that being said, there is one last concept, which is putting the equals definition in the proper place. You need to put it inside your Fraction class and define it like this...
public boolean equals(Fraction other) {
// do something like this (you will have to define toDouble)
if(this == other || this.toDouble() == other.toDouble()) {
return true;
}
return false;
}
This will override the default...
public boolean equals(Object other) {/* ... */}
And it will make it EXTREMELY convenient. Here is some sample code of how...
Fraction fractionA = new Fraction("2/4");
Fraction fractionB = new Fraction("1/2");
Fraction fractionC = new Fraction("1/3");
Object trollObject = new Object();
// And then call random equals objects...
if(fractionA.equals(fractionB)) {
// should be true...
}
if(fractionB.equals(fractionA)) {
// should be true...
}
// This avoids having to do any casting because
// since you've only defined a Fraction.equals(Fraction) method
// it should instead default to the Object.equals method
if(trollObject.equals(fractionB)) {
}
Here's a quite standard pattern:
public boolean equals(Object other) {
if (other == this) return true;
if (other == null) return false;
if (other.getClass() != this.getClass()) return false;
Fraction o = (Fraction) other;
// now you compare their num, den, and possibly sign
}
People may argue if we should use getClass() or instanceof. It matters only if Fraction is extended, and it depends on what you want if it is extended. Just keep in mind a contract of equals() is a.equals(b) should get the same result as b.equals(a) if neither one is null, and a subclass may have a different equals() that potentially breaks the contract.
== operator compares hash codes of objects. That is reason why your method is not ok, you should write it like this :
public boolean equals(Object other){
if (other instanceof Fraction){
return ((Fraction)other).getNum == this.num && ((Fraction)other).getDen == this.den;
} else {
return false;
}
}
I hope that it will helpful to you .try this code.
import java.io.*;
class Cast
{
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
byte a=20;
short s=31468;
int i=12345678;
char c=’c';
float f=3.56f;
//Widening or promotion [java question bank][1]
System.out.println(“a=(short) “+(short) a);
System.out.println(“a=(int) “+(int) a);
System.out.println(“a=(long) “+(long)a);
System.out.println(“a=(float) “+(float)a);
System.out.println();
System.out.println();
System.out.println(“s=(int) “+(int)s);
System.out.println(“s=(long) “+(long)s);
System.out.println(“s=(float) “+(float)s);
System.out.println();
System.out.println();
System.out.println(“i=(long) “+(long)i);
System.out.println(“i=(float) “+(float)i);
System.out.println(“i=(double) “+(double)i);
//Narrowing using [java question bank][2]
System.out.println(“f=(byte) “+(byte)f);
System.out.println(“f=(short) “+(short)f);
System.out.println(“f=(char) “+(char)f);
System.out.println(“f=(long) “+(long)f);
System.out.println();
System.out.println();
System.out.println(“i=(byte) “+(byte)i);
System.out.println(“i=(short) “+(short)i);
System.out.println();
System.out.println();
System.out.println(“s=(byte) “+(byte)s);
}
}

An efficient equals(Object o) implementation

I read this SO post after I wrote out the title but still decided to go through with the question on bug-proof implementations of equals in Java. This is my normal implementation
#Override
public boolean equals(Object o){
if(o == null) return false;
if(o instanceof CompositePk == false) return false;
if(this == o) return true;
CompositePk that = (CompositePk)o;
return new EqualsBuilder().append(this.id, that.id)
.append(this.bucketId, that.bucketId)
.isEquals();
}
using Apache's EqualsBuilder to do the mundane stuff. Even easier than this is my Netbean's automatically generated equals(o) implementation
#Override
public boolean equals(Object obj){
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final TemplatesWrapper other = (TemplatesWrapper) obj;
if (this.timeAdded != other.timeAdded && (this.timeAdded == null || !this.timeAdded.equals(other.timeAdded))) {
return false;
}
return true;
}
I take these from 2 diff projects but they both try to accomplish the same thing but using diff approaches. Which style would you rather or are there any flaws you spot?
First of all, there's no need to test for null, then test for instanceof, since foo instanceof Bar evaluates to false when foo is null.
It's weird to compare the result of the instanceof operator to false, since instanceof is a boolean operation.
Comparing classes with getClass() is at best controversial. Joshua Bloch, who wrote much of the Java collections framework and a lot of other important stuff besides, says
This technique ("getClass-based equals
methods") does satisfy the equals
contract, but at great cost. The
disadvantage of the getClass approach
is that it violates the "Liskov
Substitution Principle," which states
(roughly speaking) that a method
expecting a superclass instance must
behave properly when presented with a
subclass instance. If a subclass adds
a few new methods, or trivially
modifies behavior (e.g., by emitting a
trace upon each method invocation),
programmers will be surprised when
subclass and superclass instances
don't interact properly. Objects that
"ought to be equal" won't be, causing
programs to fail or behave
erratically. The problem is
exacerbated by the fact that Java's
collections are based on the equals
method.
You should use instanceof instead of comparing via getClass() unless you have some specific technical reason not to.
After establishing that the other object is comparable to this, you then compare primitives with == and objects with equals. It's more complicated if any of your member objects can be null; you must then write verbose clauses to compare possibly null things to each other (or write a bothNullOrEqual(Object a, Object b) method).
The EqualsBuilder approach looks bogus to me, but that's just a "smell", which I won't argue against technically. In general, I don't like extra method calls in a method that may be called frequently.
The Apache one is bogus because it tests for null and uses the getClass() comparison.
Here's mine:
#Override
public boolean equals(final Object o) {
if (!(o instanceof MyClass))
return false;
final MyClass om = (MyClass)o;
// compare om's fields to mine
}
I would do it this way:
public boolean equals(Object ob) {
if (ob == null) return false;
if (ob == this) return true;
if (!(ob instanceof MyClass)) return false; // OR
if (ob.getClass() != getClass()) return false;
// check relevant members
}
The two lines in the middle are different. One allows for subclasses to be equal (the first one), the other doesn't. Use whichever one is appropriate.
To give you an example, Java's AbstractList class will probably use the second form, because the exact implementation of List is irrelevant. what matters is if the members are equal and in the same position.
Conversely, a Person class should use the first form (instanceof) because if there is a Student subclass and you call Person.equals(Student) it may return true without checking the extra fields in Student whereas Student.equals(Person) will probably return false. If equals() isn't commutative, you're asking for trouble.
I tend to use equals() methods generated by my IDE (IntelliJ IDEA) rather than creating an unnecessary dependency to some Apache library for little gain.
Apache's is better than yours or cletus'.
As far as my vague memory suggests, there is a problem with using instanceof in equals; I can't quite put my finger on why yet, perhaps someone will elaborate. I could be wrong.
-- Edit:
As Chris and Steve helpfully explain below, I was thinking of the "symmetric property" of equals implementation. On this basis, I can back up my claim of prefering the Apache implementation :)
Honestly, the less code you have to write, the better off you are (in most cases).
The code that's generated has been debugged and used by many MANY people. You might as well use what's generated (and if you need to enhance the performance, do so).
The advantage of using the generated code: any time your instance fields changes (and this generated code wasn't modified), you can simply regenerate code.
Sometimes, it's easier to think about maintainability. Rule of thumb: the less code you write yourself, the less you have to debug. If the generated code doesn't take a huge performance hit, generate it!
Explanation: When overriding the equals method, the hashCode() method must be overrided too. So, considering a class with 3 properties as show below and considering that all the properties are significant to equality, the equals() implementation must test all these fields. The order of conditionals isn't important, but all the fields must to be tested for equality to consider the equality between objects at all.
public class SampleClass {
private Long id;
private String description;
private Date creation;
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((creation == null) ? 0 : creation.hashCode());
result = prime * result + ((description == null) ? 0 : description.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
boolean isEquals = true;
if (this == obj) { isEquals = true; }
else if (obj == null) { isEquals = false; }
else if (getClass() != obj.getClass()) { isEquals = false; }
else {
SampleClass other = (SampleClass) obj;
if (creation == null) {
if (other.creation != null) isEquals = false;
} else if (!creation.equals(other.creation)) {
isEquals = false;
} else if (description == null) {
if (other.description != null) isEquals = false;
} else if (!description.equals(other.description)) {
isEquals = false;
} else if (id == null) {
if (other.id != null) isEquals = false;
} else if (!id.equals(other.id)) {
isEquals = false;
}
}
return isEquals;
}

Categories

Resources