I am trying to test a class for a test-assignment poker-game in which it is only important to determine the validity or value of particular hands.
My PokerHand
object contains a TreeSet<Card>
. I thought this would be an ideal data-structure since doubles are not allowed, and it automagically sorts it with red-black tree algorithm.
The problem however, is that it appears to have some side-effects that I am not yet aware of. I understand that doubles will not be added to a TreeSet
, but in my tests I make sure not to. Instead I noticed that it will not add new Card
objects to the TreeSet as soon as the number
fields are equal, but not the type.
This is the equals method for a Card
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Card other = (Card) obj;
return this.type == other.type && this.number == other.number;
}
This is the test, adding various cards...
@Test
public void testOnePair() {
hand.addCard(new Card(3, Card.CARD_TYPE.SPADES));
hand.addCard(new Card(8, Card.CARD_TYPE.CLUBS));
hand.addCard(new Card(10, Card.CARD_TYPE.HEARTS));
hand.addCard(new Card(14, Card.CARD_TYPE.SPADES));
hand.addCard(new Card(14, Card.CARD_TYPE.CLUBS));
assertEquals("One Pair", this.hand.getValue());
}
What appears to be happening is that the last Card
is not added, so the size of the TreeSet
effectively remains 4
, even though the cards are clearly distinct. It does not even consult the equals method.
It does however reach the compareTo
method.
@Override
public int compareTo(Object t) {
if (t.getClass().equals(this.getClass())) {
Card otherCard = (Card)t;
if (otherCard.equals(this)) {
return 0;
}
return this.number - otherCard.number;
}
else {
throw new ClassCastException("Cannot convert " + t.getClass().toString() + " to Card");
}
}
It has been a while since I've gotten back into Java 8 and maybe I'm just clearly overseeing something. I hope somebody can help me forward with this.
I've always been reluctant to ask questions here. Solved this as soon as I submitted it... Wanted to share this with you. TreeSet
only cares about the compareTo
method. So I changed it to be the following.
@Override
public int compareTo(Object t) {
if (t.getClass().equals(this.getClass())) {
Card otherCard = (Card)t;
if (this.number == otherCard.number) return this.type.compareTo(otherCard.type);
return this.number - otherCard.number;
}
else {
throw new ClassCastException("Cannot convert " + t.getClass().toString() + " to Card");
}
}
This solved it, because now the comparable contract is "aware" of the type properties.
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.