我想知道在(a)没有足够的信息来确定 C 的两个实例是否相等或(b)调用方法的情况下,覆盖 C 类对象的equals
(and ) 方法的正确 Java 编程范式是什么hashCode
应该无法确定 C 的两个实例是否相等。
例如,在我的项目中,我有一PlayingCard
堂课。在我看来,如果 aPlayingCard
面朝上,那么调用方法应该可以访问它的属性,但如果它面朝下,那么这些属性应该保持未知:
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; }
看起来,为了 Java 集合框架,如果两张牌具有相同的点数和花色,它们应该是相等的:
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;
}
}
但这透露了太多信息:
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;
}
}
使用getRank
and 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
其他开发人员是如何处理这种情况的?在这种情况下投掷某种东西RuntimeException
是合适的吗?感谢您的任何意见和想法。