当等于无法确定时,Java等于

jay*_*jay 12 java equals

我想知道在(a)没有足够的信息来确定C的两个实例是否相等或者(b)调用方法的情况下,覆盖C类对象的equals(和hashCode)方法的正确Java编程范例是什么?不应该能够确定两个C实例是否相等.

例如,在我的项目中,我有一个PlayingCard班级.在我看来,如果a PlayingCard面朝上,那么调用方法应该可以访问其属性,但如果它面朝下,那么这些属性应该保持未知:

class PlayingCard {
    private Rank rank;
    private Suit suit;
    private boolean isFaceDown;

    public PlayingCard(Rank rank, Suit suit, boolean isFaceDown) {
        this.rank = rank;
        this.suit = suit;
        this.isFaceDown = isFaceDown;
    }

    public Rank getRank() { return isFaceDown ? null : rank; }

    public Suit getSuit() { return isFaceDown ? null : suit; }
Run Code Online (Sandbox Code Playgroud)

似乎,为了Java Collections Framework,如果两个扑克牌具有相同的等级和套装,它们应该是相同的:

    public boolean equals(Object obj) {       // attempt #1
        if(this == obj) return true;
        if(obj == null) return false;
        if(!(obj instanceof PlayingCard)) return false;
        PlayingCard other = (PlayingCard) obj;
        if(rank != other.rank) return false;
        if(suit != other.suit) return false;
        return true;
    }
 }
Run Code Online (Sandbox Code Playgroud)

但这揭示了太多的信息:

class Malicious {

    public Rank determineRankOfFaceDownCard(PlayingCard faceDownCard) {
        Set<PlayingCard> allCards = /* a set of all 52 PlayingCards face up */;
        for(PlayingCard c : allCards) {
            if(c.equals(faceDownCard)) {
                return c.getRank();
            }
        }
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用getRank和getSuit`方法似乎也不起作用:

    public boolean equals(Object obj) {       // attempt #1
        if(this == obj) return true;
        if(obj == null) return false;
        if(!(obj instanceof PlayingCard)) return false;
        PlayingCard other = (PlayingCard) obj;
        if(getRank() != other.getRank()) return false;
        if(getSuit() != other.getSuit()) return false;
        return true;
    }
}

/* outside the PlayingCard class */

Set<PlayingCard> s = new HashSet<PlayingCard>();
s.add(new PlayingCard(Rank.ACE, Suit.SPADES, true));
s.contains(new PlayingCard(Rank.TWO, Rank.HEARTS, true)); // returns true
Run Code Online (Sandbox Code Playgroud)

其他开发人员如何处理这种情况?这种情况下投掷某种形式RuntimeException是否合适?感谢您的任何意见和建议.

tib*_*tof 6

您可以在equals方法中添加此条件:

if(this.isFaceDown || other.isFaceDown) return false;
Run Code Online (Sandbox Code Playgroud)

我认为这是完全隐藏卡片的唯一方法,如果卡片面朝下.问题是,如果将要添加的卡面朝下,将其添加到集合中时可能会出现重复.