简体   繁体   English

TreeSet无法正确添加不同的数据

[英]TreeSet does not properly add distinct data

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> . 我的PokerHand对象包含一个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. 我知道不会将double值添加到TreeSet ,但是在我的测试中,请确保不会添加。 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. 相反,我注意到,一旦number字段相等,它就不会将新的Card对象添加到TreeSet中,但不会立即添加类型。

This is the equals method for a Card 这是一张Card的equals方法

@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. 似乎正在发生的事是没有添加最后一个Card ,因此即使这些Card明显不同, TreeSet的大小实际上仍为4 It does not even consult the equals method. 它甚至不咨询equals方法。

It does however reach the compareTo method. 但是,它确实达到了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");
    }
}

It has been a while since I've gotten back into Java 8 and maybe I'm just clearly overseeing something. 自从我回到Java 8以来已经有一段时间了,也许我只是清楚地监督了一些事情。 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. TreeSet只在乎compareTo方法。 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. 解决了它,因为现在可比较的合同“知道”类型属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM