【问题标题】:Java Comparing two identical objects gives false [duplicate]Java比较两个相同的对象给出错误[重复]
【发布时间】:2016-03-30 21:36:09
【问题描述】:

我有一个名为 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(),但输出是相同的。

【问题讨论】:

  • 您不会在代码中的任何位置覆盖compareTo
  • 阅读 equals() 的 javadoc。这就是你如何知道一个方法做了什么以及为什么它返回 false。
  • 我只是没有在此处添加它,否则它看起来像一团糟
  • @AlexisC。 compareTo 无关紧要。 OP 使用 equals()。
  • 那么实现Comparable有什么意义呢?

标签: java object equals contains


【解决方案1】:

您的 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,这样如果两张卡彼此相等,它们的哈希码也将相等。

【讨论】:

  • 并且每当equals 被覆盖时,hashCode 也必须被覆盖。
  • @Henry 没错
【解决方案2】:

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

当您想按值比较对象时,您必须创建自己的 equals 方法,该方法比较 ranksuit 的值。这可能很困难,因为您还必须验证两个对象都不是 null 并且对象类型能够安全地从 Object 转换它。这称为按值比较。

一个有用的技巧是使用 Eclipse 生成 equals 函数。

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-02
      相关资源
      最近更新 更多