在扑克游戏中对Card对象的哈希码的建议?

时间:2011-05-22 16:17:20

标签: java hashcode

如何为包含enum suit和enum rank的卡对象计算哈希码?

3 个答案:

答案 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()实现:

context menu screenshot

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-12Suit序数为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; )
相关问题