1

I have a custom class called Card

public class Card implements Serializable, Comparable<Card>{
private static final long serialVersionUID = 100L;
private Rank rank;
private Suit suit;

public Card(Rank rank, Suit suit){
    this.rank = rank;
    this.suit = suit;
}

public enum Rank{
    TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6), SEVEN(7), EIGHT(8), NINE(9), TEN(10), JACK(10), QUEEN(10), KING(10), ACE(11);
    private final int value;

    Rank(int value){
        this.value = value;
    }
} 

public enum Suit{
    CLUBS, DIAMONDS, HEARTS, SPADES;

    public static Suit getSuit(){
        Random rand = new Random();
        return values()[rand.nextInt(values().length)];
    }
}

To check if they're the same I'm doing this:

Card smth = new Card(Card.Rank.ACE,Card.Suit.CLUBS);
Card smth1 = new Card(Card.Rank.ACE,Card.Suit.CLUBS);

System.out.println(smth.equals(smth1));

but its always giving me false and I have no idea why is that, I've also tried putting them in an ArrayList and checking with contains() but the output is the same.

RnD
  • 1,019
  • 5
  • 23
  • 49

3 Answers3

3

Your Card class must override equals in order to define when two Card instances should be considered equal.

@Override
public boolean equals (Object other)
{
    if (this == other)
        return true;
    if (!(other instanceof Card))
        return false;
    Card oc = (card) other;
    return this.rank.equals(oc.rank) && this.suit.equals(other.quit);
}

Also override hashCode, so that if two Cards are equal to each other, their hash codes would also be equal.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
Eran
  • 387,369
  • 54
  • 702
  • 768
2

The default implementation of equals() compares objects by their adress in memory. Meaning different objects will be considered unequal. This is called comparing by identity.

When you want to compare objects by value, you have to create you own equals method, which compares the values of rank and suit. This can be difficult because you also have to verify neither of the objects is null and very the object type to be able to safely cast it from Object. This is called comparing by value.

A useful tip for this is to generate the equals function using Eclipse.

Thirler
  • 20,239
  • 14
  • 63
  • 92
0

The default implementation of equals considers only reference equality, that is, v1==v2. This, two different instances containing the same values won't compare equal. You can choose one of two strategies:

  • Overriding equals to return true for objects that represent the same information. Usually, this implies comparing the fields of both objects in some way. The values of some fields might not matter, e.g. if you're object keeps some sort of cache, then the equals method might ignore it on comparisons. Note that you also need to override the hashcode method to be consistent with equals.
  • Designing your class so that only one instance of every different conceptual "value" is created. Obviously, this doesn't work well with mutable or non-final classes, but you don't need to override equals or hashcode. This is what enums do: only a single instance of each enum value exists, and so you can compare them with ==. In order to go this route, you need to disable publically accessible constructors and provide some kind of factory method to either return of (if never previously created) construct the instance in question. The disadvantage is that for large number of different values this route wastes significant memory.
Javier Martín
  • 2,537
  • 10
  • 15