我遇到了一个非常奇怪的问题。我写了一个简单的Deck
课程,它代表了一张标准的52张扑克牌。该类有一个方法missingCards()
,它返回从牌组中抽出的所有牌组。如果我尝试使用.equals()
比较两组相同的缺失卡片,我告诉他们它们是不同的,如果我检查一个集合是否包含我知道的元素是否使用.contains()
我是已退回false
。
这是我的测试代码:
public void testMissingCards()
{
Deck deck = new Deck(true);
Set<Card> drawnCards = new HashSet<Card>();
drawnCards.add(deck.draw());
drawnCards.add(deck.draw());
drawnCards.add(deck.draw());
Set<Card> missingCards = deck.missingCards();
System.out.println(drawnCards);
System.out.println(missingCards);
Card c1 = null;
for (Card c : drawnCards){
c1 = c;
}
System.out.println("C1 is "+c1);
for (Card c : missingCards){
System.out.println("C is "+c);
System.out.println("Does c1.equal(c) "+c1.equals(c));
System.out.println("Does c.equal(c1) "+c.equals(c1));
}
System.out.println("Is c1 in missingCards "+missingCards.contains(c1));
assertEquals("Deck confirm missing cards",drawnCards,missingCards);
}
(编辑:为了清楚起见,我在注意到测试失败后添加了两个循环。第一个循环从drawnCards中取出一张卡,然后对着missingCards中的每张卡检查此卡 - 它总是匹配一个,因此该卡必须包含在missingCards中。但是,missingCards.contains()失败)
这是一个输出的例子:
[5C, 2C, 2H]
[2C, 5C, 2H]
C1 is 2H
C is 2C
Does c1.equal(c) false
Does c.equal(c1) false
C is 5C
Does c1.equal(c) false
Does c.equal(c1) false
C is 2H
Does c1.equal(c) true
Does c.equal(c1) true
Is c1 in missingCards false
我完全相信我的卡类上的.equals的实现是正确的,正如你从输出中看到它确实有效!
这里发生了什么?
干杯,
皮特
答案 0 :(得分:11)
您忘记以与hashCode() :)一致的方式实施equals() :) (即,相等的对象必须返回相同的哈希码)。
答案 1 :(得分:8)
Java - 在OpenJDK 6上是否打破了Set.contains()?
不,不是。
调试Java的第一条规则是99.9%的时间你的代码被破坏,而不是Java标准库。
答案 2 :(得分:3)
hashCode怎么样?根据Joshua Bloch的“Effective Java”chapter 3,你应该总是将两者叠加在一起。
发布您的卡类。那时很容易发现。
答案 3 :(得分:2)
请发布Deck
课程的代码 - 至少equals(Object)
和hashCode()
方法。
我的第一个猜测是您只实施了equals()
,而不是hashCode()
。如果是这种情况,请阅读java.lang.Object
类的文档。