-1
public class Card
{   
    long id;
    String name;
    Rank rank;
    long price;

    public Card(long id, String name, Rank rank)
    {
        this.id = id;
        this.name = name;
        this.rank = rank;
        this.price = 0;
    }

    public String toString()
    {
        return "id: " + this.id + "\n" + "name: " + this.name + "\n" + "rank: " + this.rank + "\n" + "price: " + this.price;
    }

    public boolean equals(Card card)
    {
        if (this.id == card.id)
        {
            if (this.name.equals(card.name))
            {
                if (this.rank == card.rank)
                {
                    return true;
                }
            }
        }
        return false;
    }

    public int hashCode()
    {
        return id.hashCode() + name.hashCode() + rank.hashCode();
    }
}

I wrote a class Card with id, name, price and rank which is enum Rank.

I'm trying to override equals and hashCode. The two cards compared should be considered equal only if the id, name, and rank are the same.

I get "long cannot be dereferenced". I can't just use id itself cus it's long not int.

C Kim
  • 11
  • 1
  • See answer below. Also note that most IDEs (for example Eclipse) can generate good equals and hashCode methods for you that work and follow best practices (i.e. generate good hash codes). – ewramner Apr 13 '20 at 15:32

4 Answers4

1

First, your equals is not correct. You can't change the signature of Object.equals(Object). Second, long is not an object type. So, you can't invoke hashCode() on it. But you can pass it to the Long.hashCode(long) method. Finally, always use the Override annotation when you intend to override a method to prevent the first class of bug. Like,

@Override
public boolean equals(Object o) {
    if (o instanceof Card) {
        Card card = (Card) o;
        if (this.id == card.id) {
            if (this.name.equals(card.name)) {
                if (this.rank.equals(card.rank)) {
                    return true;
                }
            }
        }
    }
    return false;
}

@Override
public int hashCode() {
    return Long.hashCode(id) + name.hashCode() + rank.hashCode();
}
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • Probably mine is a dumb question, there is some specific reason for use a three branch if instead of a three and cond in the equals method ? Thanks in advance for the answer. – dariosicily Apr 13 '20 at 15:49
  • 1
    @dariosicily That is how OP wrote it. I fixed the bugs. `==` to `.equals` for `rank` and the method signature. `return this.id == card.id && this.name.equals(card.name) && this.rank.equals(card.rank);` is probably how I would have written it. With additional checks for `null` (and perhaps an object identity check optimization). – Elliott Frisch Apr 13 '20 at 16:22
  • I missed the return cond , thanks for your time and explanation. – dariosicily Apr 13 '20 at 16:31
1

Instead of

return id.hashCode() + name.hashCode() + rank.hashCode();

Use:

return Objects.hash(id, name, rank);

Objects.hash gives a better distribution than just adding numbers together. Also you don't have to worry about null values or the right way to compute the hash code for primitive types.


Note that this involves autoboxing the primitive long to the wrapper class Long. It also creates a temporary object array because hash is a varargs method.

Joni
  • 108,737
  • 14
  • 143
  • 193
0

Change long id to Long id. Note that Long is a wrapper class whereas long is a primitive type. Primitive types do not have any method/functions to call on them.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
0

You cannot call methods directly on primitives, they must be boxed. Please use Long.valueOf(id).hashCode() or Long.hashCode(id) instead of just id.hashCode(). Java's primitives are not the same as it's objects, and although it does autoboxing when you pass primitives to methods expecting objects and vice versa, it cannot do so here. If you want, read the docs here: https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html

user
  • 7,435
  • 3
  • 14
  • 44