简体   繁体   中英

Overriding equals method for comparing two fractions

I'm currently working on a project where I need to compare two fractions. I have not done such a thing before, overriding a method, so I need a little help.

Here is the thing that bothers me;

So I have a class called fraction, and in that class, I have two fields.

public class Fraction {

private int denominator;
private int numerator;

public Fraction(int numerator, int denominator) {

    //Throwing an error if the denominator is 0.
    if (denominator == 0) {
        throw new IllegalArgumentException("Denominator cannot be zero!");
    }
    //When both numbers are negative
    if (denominator < 0 && numerator < 0) {
        denominator *= -1;
        numerator *= -1;
    }
    //When the numerator is negative
    if (denominator < 0 && numerator > 0) {
        denominator *= -1;
        numerator *= -1;
    }

    this.denominator = denominator;
    this.numerator = numerator;
}

public Fraction(int numerator) {
    this.numerator = numerator;
    this.denominator = 1;
}

public Fraction() {
    this.numerator = 0;
    this.denominator = 1;
}

I also have a couple of other useful methods for me to compare two fractions like this:

//converts the current fraction to the lowest terms
public void toLowestTerms() {
    int reminder = 0, gcd = 0;
    int up = numerator, bottom = denominator;

    while (up != 0 && bottom != 0) {
        reminder = up % bottom;
        up = bottom;
        bottom = reminder;
        gcd = up;
    }
    numerator /= gcd;
    denominator /= gcd;
}

So here is the part I am stuck.

@Override
//must take in an "Object" to properly override the Object class's equals method, but should ultimately check if two fractions are equal
public boolean equals(Object obj) {

    // If the object is compared with itself then return true
    if(obj == this){
        return true;
    }

    /* check if o is an instance of Complex or not
      "null instanceof [type]" also returns false */
    if (!(obj instanceof Fraction)) {
        return false;
    }

    //This object is created for
    Fraction compareObject = new Fraction(this.getNumerator(), this.getDenominator());
    compareObject.toLowestTerms();

    // typecast o to Fraction so that we can compare data members
    Fraction x = (Fraction) obj;

    //converting to the lowest terms to compare
    ((Fraction) obj).toLowestTerms();

    // Compare the data members and return accordingly
    return (compareObject.getNumerator()== x.getNumerator() && compareObject.getDenominator() == x.getDenominator());
}

Is this the right thing to do, or is there a way to do this properly? Technically I am creating an object to make use of the toLowestTerms method. Because when I want to compare, for example, 1/2 == 12/24, I need to reduce the numerator and denominator to do a good check.

'Fraction compareObject = new Fraction(this.getNumerator(), this.getDenominator());
compareObject.toLowestTerms();`  

Your code seems good to me, I think it will work. I would add a few points, mostly about your comments:

1.

If the object is compared with itself then return true

If the object is identical (ie the same instance)

2.

instance of Complex

You mean instance of Fraction ?

3. It seems your method toLowestTerms changes the current instance this . For that reason, you created a new instance to represent this , called compareObject , I can only assume so that you don't alter this when compare is called (a good thing!). But for the parameter obj , you are altering the instance! You did not make a copy. You can simply solve this by making the copy as well, but might I suggest that your toLowestTerms method returns a new copy of Fraction with the lowest terms? Then you can safely call it on both this and obj , get fresh new copies, and compare both.

4. A even more deep design decision would be to force call toLowestTerms on the constructor/setters. So that it's impossible to have a Fraction that is not on the lowest terms. That would greatly simplify methods like equals , hashCode . But that is a deeper design decision you would need to make. If you do so, you can take a look at a library called Lombok who would generate equals and hashCode for you based on the properties of the class! But will not do further calculations like toLowestTerms .

5. If you are implementing equals, you probably want to implement hashCode as well, and make sure they are compatible.

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