0

I have a program that represents a deck of cards using an ArrayList and I want to compare two decks to see if they are equal (have the same size, same cards, and in the same order). I know you can do list1.equals(list2) for a type like int and it will return true if both are: (1,2,3) for example. When I try to do that with a list of Card objects it returns false . My code to create the deck is:

public DeckofCards(){
    for (Suits s : Suits.values()) {
        for(Values v : Values.values()){
            card = new Card(v,s);
            deck.add(card);
        }  
    }
}

And I also have a method: deckToList which just returns deck. So if I do:

DeckofCards dc = new DeckofCards();
DeckofCards dc2 = new DeckofCards();
List<Card> l1 = dc.deckToList();
List<Card> l2 = dc2.deckToList();

l1.equals(l2);

That returns false even though if I print out both l1 and l2 they have the same cards in the same order since I didn't manipulate the decks. Now if I set both l1 and l2 to dc then it returns true. Since I am using an Object does the equals method just look at the address and not the values? I'm not really sure what is going on or how to correctly compare the two.

Ryan Sayles
  • 3,389
  • 11
  • 56
  • 79

3 Answers3

0

According to implementation of Abstract List's equals methos the super class of ArrayList which can be found here

You should override equals method of Card class

Good implementation when talking about cards is check whether their values and colors are equal

Something like this might work

@Override
   public boolean equals(Object other){
       if(this == other) return true;

       if(other == null || (this.getClass() != other.getClass())){
           return false;
       }

       Card otherCard = (Card) other;
       return (this.value == otherCard.value) &&
              (this.color == otherCard.color);
   }
Ziker
  • 877
  • 2
  • 10
  • 30
0

Your card object dont implement a good equals

if you see the implementation of the equals on the ArrayList (actually AbstractList), you see that iterates on both list and try to the equals the elements.

Mattos
  • 799
  • 1
  • 9
  • 16
0

When you call the constructor DeckofCards(), it is creating both a new List and a new Card for every value - the clue is the keyword new. This means that a new memory location is allocated for all of those objects. So when you create two DeckofCards objects they each contain their own List object which contains 52 Card objects: 104 separate Card objects in total.

Unless a class overrides the equals method it will use the default provided by Object, which just compares memory locations. Now, List does override equals and it does this by calling equals on each of the Card objects it contains, but since it does not override equals then the default Object version will be called. All the Cards are in different memory locations albeit some have the same value (in different DeckOfCards objects), therefore these List objects are not equal.

So the advice is override equals, Ziker's implementation looks fine. But in general, if you override equals don't forget to override hashcode, too, otherwise you will get terrible performance from Collections such as HashSet or HashMap.

Robert
  • 8,406
  • 9
  • 38
  • 57