equals method - how to override

1.9k Views Asked by At

I need help on to override the equals method. I have everything working except for the equals method. The equals method that I currently have is not giving me the correct answer. I can not seem to figure out what could be the problem.

My Class:

package myclasses;

public class Currency
{
    private int dollars, cents;

    public Currency()
    {
        dollars = 0;
        cents = 0;
    }

    public Currency(int d, int c)
    {
        this.dollars = d;
        this.cents = c;

        setCents(cents);
    }

    public int getDollars()
    {
        return dollars;
    }

    public int getCents()
    {
        return cents;
    }

    private void setDollars(int dollars)
    {
        this.dollars = dollars;
    }

    private void setCents(int cents)
    {       
        while(cents > 99)
        {
            cents = (cents - 100);
            dollars++;
        }

        this.cents = cents;
    }

    public void setAmount(int newDollars, int newCents)
    {
        setDollars(dollars);
        setCents(cents);
    }

    public void add(int dollars, int cents)
    {
        this.dollars =  dollars + getDollars();
        cents = cents + getCents();

        setCents(cents);
    }

    public boolean equals(Object dollars, Object cents)
    {
        if(this == dollars && this == cents)
            return true;

        if(!(dollars instanceof Currency) || !(cents instanceof Currency))
            return false;

        Currency money = (Currency) dollars;
        Currency penny = (Currency) cents;

        return (this.dollars == money.dollars) && (this.cents == penny.cents);
        //return Currency.dollars.equals(Currency.cents);
        //return this.equals(dollars) && this.equals(cents);

    }

    public boolean isZero()
    {
        if(getDollars() == 0 && getCents() == 0)
        {
            return true;
        }
        return false;
    }

    public String toString()
    {
        return "$" + getDollars() + "."   +
                (getCents() < 10 ? ("0" + getCents()) : getCents());
    }
}
3

There are 3 best solutions below

4
On

Your equals() method has some errors like:

if(this == dollars && this == cents)

This will never be true... this must be:

if(this.dollars == dollars && this.cents == cents)

But I won't put any effort in coding the equals, is recommended to autogenerate equals. Something like this:

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Currency other = (Currency) obj;
    if (cents != other.cents)
        return false;
    if (dollars != other.dollars)
        return false;
    return true;
}

Also is highly recommended, (nearly unavoidable as @AdriaanKoster commented) when you override equals() method, also override hashCode()
In equals() definition:

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

Hash code:

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + cents;
    result = prime * result + dollars;
    return result;
}
0
On

I'm not quite sure why you are going the first check in your equals method. But I'll tell you how I am usually doing my equals method

public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    } else if (obj == null) {
        return false;
    } else if (getClass() != obj.getClass()) {
        return false;
    }

    //a cast of object to the class you are using should be here
    if (this.someField.equals(castObject.someField)
            && this.otherField.equals(castObject.otherField)) {
        return true;
    }

    return false;
}

So here's what's happening. The first part of the method does basic checks - whether the object that you are testing is the same as the parameter, whether the object is null, and whether they are from the same class. Note that they are else if's because there are more than just those 3 cases.

If you've not entered any of the 3 initial conditional statements, you will need to make a cast of the obj parameter to the class that you are in. You are safe to do so because of the last if -

else if (getClass() != obj.getClass()) {
    return false;
} 

After that simply define the rule by which you determine whether two objects are the same. In the example that I'm using, I'm checking the contents of two fields of the class. If they are the same, then the objects are equal.

0
On

If you are overriding equals method, then your above code is not correctly overriding equals method.

use below code instead for overriding equals--

public boolean equals(Object currency) {

Currency newref = null;

if (currency instanceof Currency) {
  newref = (Currency)currency;
}
return (this.dollars == newref.dollars) && (this.cents == newref.cents);
}