简体   繁体   中英

Why does my custom equals method (doubles and integers) not work?

I have a custom equals to check the equality of my object called Pair.

class Pair implements Comparable <Parr> {

double coef;
int power;

Pair(double a, int b) {
    coef = a; 
    power = b; 
}

My custom equals method is (located in class pair):

@Override
public boolean equals(Object o) {
    if (!(o instanceof Pair))
        return false; 
    Pair that = (Pair) o; 
    return that.coef == this.coef && that.power == this.power; 
}

I've checked with print my object if the objects are the same, and they are indeed the same.

1.0 1 2.0 0
1.0 1 2.0 0 

I call my custom equals from a different file, called Test.

class Test {

public static void main(String[] args) {
    orig = pol1.differentiate().integrate();
    System.out.print(orig);
    if (orig.equals(pol1))
        System.out.println(" (is equal.)");
    else
    System.out.println(" (is not equal.)"); 

And my class Polynomial, which is an arraylist with objects of Pair inside.

class Polynominal implements PolynominalInterface {


ArrayList<Pair> terms = new ArrayList<Pair>(); 

I looked on the internet, and I found that I cannot use == in my Equals method, but I'm using Intergers and Doubles, so equals() would not work.

Can anyone point me in the right direction?

If orig and pol1 are instances of Polynomial then this

if (orig.equals(pol1))

would only work if you implement Polynomial#equals() as well; which would iterate the two ArrayList s and make sure individual Pair s are equal (using Pair#equals() of course).

Ok, thanks to Ravi Thapliyal I found the solution.

After adding an custom equals method in my Polynominal class, the problem was fixed.

@Override
public boolean equals(Object o) {
    if (!(o instanceof Polynomial))
        return false; 
    Polynomial that = (Polynomial) o; 
    return that.terms.equals(terms); 
}

Use the Double.compare(double, double) method instead of ==.

Floating point comparison is "fuzzy" in Java.

You would need to implement a Polynomail.equals() method something like the following:

public boolean equals(Object o) {
  if (!(o instanceof Polynomial)) return false;

  Polynomial other = (Polynomial) o;

  if (this.terms==null && other.terms==null) return true;

  // A suitable equals() method already exists for ArrayList, so we can use that
  // this will in turn use Pair.equals() which looks OK to me
  if (this.terms!=null && other.terms!=null) return this.terms.equals(other.terms);

  return false;
}

Two issues come to mind: the first is that the default hashCode() method will seldom return the same value for any two distinct object instances, regardless of their contents. This is a good thing if the equals() method will never report two distinct object instances as equal, but is a bad thing if it will. Every object which overrides Object.equals() should also override Object.hashCode() so that if x.equals(y) , then x.hashCode()==y.hashCode() ; this is important because even non-hashed generic collections may use objects' hash codes to expedite comparisons. If you don't want to write a "real" hash function, simply pick some arbitrary integer and have your type's hashCode() method always return that . Any hashed collection into which your type is stored will perform slowly, but all collections into which it is stored should behave correctly.

The second issue you may be seeing is that floating-point comparisons are sometimes dodgy. Two numbers may be essentially equal but compare unequal. Worse, the IEEE decided for whatever reason that floating-point "not-a-number" values should compare unequal to everything-- even themselves .

Factoring both of these issues together, I would suggest that you might want to rewrite your equals method to chain to the equals method of double . Further, if neither field of your object will be modified while it's stored in a collection, have your hashCode() method compute the hashCode of the int , multiply it by some large odd number, and then add or xor that with the hashCode of the double . If your object might be modified while stored in a collection, have hashCode() return a constant. If you don't override hashCode() you cannot expect the equals methods of any objects which contain yours to work correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM