Java比较两个相同的对象给出了错误

时间:2015-12-24 12:26:16

标签: java object equals contains

我有一个名为Card的自定义类

public class Card implements Serializable, Comparable<Card>{
private static final long serialVersionUID = 100L;
private Rank rank;
private Suit suit;

public Card(Rank rank, Suit suit){
    this.rank = rank;
    this.suit = suit;
}

public enum Rank{
    TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6), SEVEN(7), EIGHT(8), NINE(9), TEN(10), JACK(10), QUEEN(10), KING(10), ACE(11);
    private final int value;

    Rank(int value){
        this.value = value;
    }
} 

public enum Suit{
    CLUBS, DIAMONDS, HEARTS, SPADES;

    public static Suit getSuit(){
        Random rand = new Random();
        return values()[rand.nextInt(values().length)];
    }
}

要检查它们是否相同我正在这样做:

Card smth = new Card(Card.Rank.ACE,Card.Suit.CLUBS);
Card smth1 = new Card(Card.Rank.ACE,Card.Suit.CLUBS);

System.out.println(smth.equals(smth1));

但是它总是给我false,我不知道为什么会这样,我也尝试将它们放在ArrayList并检查contains(),但输出是相同的

3 个答案:

答案 0 :(得分:3)

您的Card类必须覆盖equals才能定义何时应将两个Card实例视为相等。

@Override
public boolean equals (Object other)
{
    if (this == other)
        return true;
    if (!(other instanceof Card))
        return false;
    Card oc = (card) other;
    return this.rank.equals(oc.rank) && this.suit.equals(other.quit);
}

同样覆盖hashCode,这样如果两张牌彼此相等,他们的哈希码也会相等。

答案 1 :(得分:1)

equals()的默认实现通过内存中的地址比较对象。意味着不同的对象将被视为不平等。这称为按身份比较。

如果要按值比较对象,则必须创建自己的equals方法,该方法会比较ranksuit的值。这可能很困难,因为您还必须验证这两个对象都不为null,并且非常符合对象类型,以便能够从Object安全地转换它。这称为按值进行比较。

一个有用的提示是使用Eclipse生成equals函数。

答案 2 :(得分:0)

equals的默认实现仅考虑引用相等性,即v1 == v2。这两个包含相同值的不同实例不会相等。您可以选择以下两种策略之一:

  • 覆盖等于对表示相同信息的对象返回true。通常,这意味着以某种方式比较两个对象的字段。某些字段的值可能无关紧要,例如如果你的对象保留某种缓存,那么equals方法可能会在比较时忽略它。请注意,您还需要覆盖hashcode方法以与equals。
  • 保持一致
  • 设计您的类,以便只创建每个不同概念“值”的一个实例。显然,这对于可变或非最终类不起作用,但是您不需要重写equals或hashcode。这就是枚举所做的:只存在每个枚举值的单个实例,因此您可以将它们与==进行比较。为了实现这条路线,您需要禁用可公开访问的构造函数,并提供某种工厂方法来返回(如果从未创建过)构造有问题的实例。缺点是,对于大量不同的值,此路由会浪费大量内存。