Java-Set.contains()在OpenJDK 6上被破坏了吗?

Java-Set.contains()在OpenJDK 6上被破坏了吗?,java,set,equals,contains,Java,Set,Equals,Contains,我遇到了一个非常奇怪的问题。我已经编写了一个简单的Deck类,它表示一个标准的52张扑克牌组。该类有一个方法missingCards(),该方法返回从组中提取的所有卡的集合。如果我尝试使用.equals()比较两组相同的缺失卡片,我会被告知它们是不同的,如果我使用.contains()检查一组卡片是否包含我知道存在的元素,我将返回false 以下是我的测试代码: public void testMissingCards() { Deck deck = new Deck(true

我遇到了一个非常奇怪的问题。我已经编写了一个简单的
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);
}
我完全确信我的card类上.equals的实现是正确的,正如您从输出中看到的,它确实有效

这是怎么回事

干杯

Pete

您忘记以与以下内容一致的方式实施:)
(即,相等的对象必须返回相同的哈希代码)。

哈希代码如何?根据Joshua Bloch的“有效Java”,您应该始终同时覆盖这两者


在课堂上张贴你的卡片。那么就很容易发现了。

请发布
Deck
类的代码——至少是
equals(Object)
hashCode()
方法

我的第一个猜测是,您只实现了
equals()
,而没有实现
hashCode()
。如果是这种情况,请阅读
java.lang.Object
类的文档

Java-Set.contains()在OpenJDK 6上被破坏了吗

不,不是


调试Java的第一条规则是,99.9%的时间是您的代码被破坏了,而不是Java标准库。

几乎可以肯定是这样。可以肯定的是,Poster应该已经发布了Card.java。谢谢你的回答,我还没有实现hashCode()。关于如何最好地实现hashCode,您有什么建议吗(一张卡片上有一个face和suit字段,这两个字段都是整数)?Eclipse将在单击一次后自动生成一个合理的hashCode并同时等于。@Peter,有效Java第二版,第9项,包含了大量的建议。一些快捷方式包括Arrays.hashCode()和Objects.hashCode()(番石榴的)嗯,我是不是错过了一个更好的方法来粘贴评论中的链接?这到底是为什么被否决了?这和被接受的答案是一样的。有一个大括号不合适,所以你在所有的卡片上循环一次,然后把最后一张放在c1中,然后检查一次。这是故意的,我非常困惑,所以我写了一些非常粗糙和准备好的测试。
[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