如何为包含enum suit和enum rank的卡对象计算哈希码?
答案 0 :(得分:3)
如果价值空间太小(是13倍?),任何两张卡都分配相同的哈希码是没有意义的。所以这完全取决于你,但是像:
A spades = 1
K spades = 2
....
A clubs = 21
K clubs = 22
....
应该没问题。
通常,如果存在大量可能的值(如每个可能的String
值或每个可能的数字列表List<Number>
)并且将它们限制为(预计),则定义哈希码是有意义的进入)有限的哈希码值空间。如果我们讨论的是由hashCode()
API定义的java.lang.Object
,那么'哈希码值的有限空间'必须符合int
类型(整数)。
答案 1 :(得分:3)
如果您正在使用Eclipse,它可以为您生成“足够好”的hashCode()
实现:
public class Card
{
private Suit suit;
private Rank rank;
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((rank == null) ? 0 : rank.hashCode());
result = prime * result + ((suit == null) ? 0 : suit.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj) return true;
if (!(obj instanceof Card)) return false;
Card other = (Card) obj;
if (rank != other.rank) return false;
if (suit != other.suit) return false;
return true;
}
}
我只能想象NetBeans,IntelliJ IDEA等也能做到这一点。
那就是说,由于域很小,这个实现同样会很好(我认为......):
public int hashCode()
{
int rankHash = ((rank == null) ? 0 : (1+rank.ordinal()));
int suitHash = ((suit == null) ? 0 : (1+suit.ordinal()));
return rankHash + 31*suitHash;
}
这假设Rank
序号为0-12
,Suit
序数为0-3
。请注意,大多数丑陋来自空检查。如果值永远不能为null,则:
public int hashCode()
{
return rank.ordinal() + 31*suit.ordinal();
}
答案 2 :(得分:2)
卡片领域(52)的空间足够小,可以容纳enum
自己。这也将为您提供一个自然的主键,因为hashCode
也应该是对象内部状态的唯一标识符。
这是一些伪Java代码,可以给你一个想法:
public enum Suit
HEART, CLUB, SPADE, DIAMOND
public enum Rank
TWO, THREE, FOUR ... KING, QUEEN, ACE
public enum Card
private final Suit suit;
private final Rank rank;
private Card(final Suit s, final Rank r);
ACE_HEARTS(ACE,HEART), TWO_HEARTS(TWO,HEART), ... KING_DIAMONDS(KING, DIAMOND);
public int hashCode() { return this.ordinal; )