2017-01-15 59 views
0

我想測試一個類的測試任務撲克遊戲中,它確定的有效性或特定手的價值是唯一重要的。TreeSet中不正確添加不同的數據

PokerHand對象包含TreeSet<Card>。我認爲這是一個理想的數據結構,因爲不允許雙打,並且它會自動將它與紅黑樹算法分類。

的問題但是,是它似乎有一些副作用,我還沒有意識到的。我知道雙打不會被添加到TreeSet,但在我的測試中,我確定不會。相反,我注意到只要number字段相同,它不會將新的Card對象添加到TreeSet,但不會是類型。

這是一個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; 
} 

這是測試equals方法,加入各種卡...

@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()); 
} 

這似乎是發生的是,最後Card是沒有添加,所以TreeSet的大小仍然有效地保留4,即使這些卡明顯不同。它甚至沒有諮詢equals方法。

但它確實達到compareTo方法。

@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"); 
    } 
} 

自從我重新回到Java 8之後已經有一段時間了,也許我只是明確地監督了一些事情。我希望有人能夠幫助我前進。

+1

對不起,但RTFM。 「_'TreeSet'實例使用其'compareTo(或compare)'method_」執行所有元素比較。根據需要,您的'compareTo'方法與'equals()'不一致。 –

回答

0

我一直都不願意在這裏提問。一旦我提交它,就解決了這個問題......希望與你分享。 TreeSet只關心compareTo方法。所以我把它改爲以下。

@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"); 
    } 
} 

這解決了這個問題,因爲現在的可比合同類型屬性的「感知」。