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);
}
}
Related
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);
Could someone help me with this question please? I've tried looking up other examples of this to find what I need to do and keep running into something called and EqualsBuilder, is that what I need to use? Do I need to have it call on equals again if it satisfies neither of the IFs?
The following code contains a class definition and an incomplete method definition. The equals method is used to compare Buildings.
It is intended to return true if Buildings have the same names and number of floors (but are not necessarily the same Building) and false otherwise.
public class Building {
private String name;
private int noOfFloors;
public boolean equals (Object rhs) {
if (this == rhs) {
return true;
}
if (!(rhs instanceof Building)) {
return false;
}
Building b = (Building) rhs;
// missing return statement
}
}
public boolean equals (Object rhs) {
if (this == rhs) {
return true;
}
if (!(rhs instanceof Building)) {
return false;
}
Building b = (Building) rhs;
// This is what you're supposed to add. It will return true only if both
// object's attributes (name and number of floors) are the same
return this.name.equals(b.name) && this.noOfFloors == b.noOfFloors;
}
The only thing that you have to test for now is the fields of both objects. If they are equal, then you should return true, if at least one of them is not then you should return false.
Since your fields in that case are int and Stringyou can use == for the integer field and .equals() for the String field.
Something like this should do the job just fine:
if(this.name.equals(b.name) && this.noOfFloors == b.noOfFloors){
return true ;
}
else{
return false;
}
After the instanceOf tests you want to compare the fields of the object to the other object. Something like Objects.deepEquals() should do the trick for you nicely.
This is my superclass equals() method:
public boolean equals(Object other){
Car c = (Car)other;
if(this.make.equals(c.make) && this.model.equals(c.model)){
System.out.println("True, Cars are equal");
return true;
}
else
System.out.println("False, Cars are not equal");
return false;
}
Here is my subclass equals() method:
public boolean equals(Object other) {
GreenCar g = (GreenCar) other;
if(super.equals(g)==true){
if (this.type.equals(g.type)) {
System.out.println("True, Cars are equal");
return true;
} else {
System.out.println("False, Cars are not equal");
return false;
}
}
else
System.out.println("False, Cars are not equal");
return false;
}
When it runs the check at if(super.equals(g)==true){ it executes the method and prints out true or false. How can I just check the return value?
You cannot run the method without letting it print anything.
This is why most of your methods should not have "side effects" (like printing things to the screen).
Remove the println calls from both equals methods. Add them to the code that calls equals instead.
In your super class, you could write something like
protected boolean equals(Object other, boolean debug) {
if (other instanceof Car) {
Car c = (Car) other;
if (this.make.equals(c.make) && this.model.equals(c.model)) {
if (debug) {
System.out.println("True, Cars are equal");
}
return true;
}
}
if (debug) {
System.out.println("False, Cars are not equal");
}
return false;
}
then you can modify your equals() method (still in the super class) like
public boolean equals(Object other) {
return equals(other, true); // <-- default to debug.
}
next your subclass should call the version that takes the debug flag like
if (super.equals(g, false)) { // you don't need == true
Alternatively, you might use a Logger and enable and disable debug on demand.
Like people have said you need to take out those println's if you want it to not print something when you call it, because every time you call the method it will print.
Just as a note you can shorten some of your methods by taking out those elses since it will have returned before getting to the next body of code if the conditional was true. For example
public boolean equals(Object other){
Car c = (Car)other;
if(this.make.equals(c.make) && this.model.equals(c.model))//if this is true
return true;//the method ends here
return false;//if the method hasn't ended yet then the conditional must be false
}
Also I noticed that you used if(super.equals(g)==true) but if you just put if(super.equals(g)) it has the same effect since you are putting in a boolean and it checks if the boolean is true or not. If you want to have the effect of if((boolean)==false) you can do if(!(boolean)) because it checks if the opposite of that boolean is true.
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;
}
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;
}