如何比较类对象?

我想比较两个对象。但是,它告诉我当我运行它时它们不匹配,即使它们匹配。请让我知道我做错了什么,谢谢。这是我的代码:

      Player p1 = new Player("Mo", "Food", 200.0,0.0);
      Player p2 = new Player("Mo", "Food", 200.0,0.0);
      
      System.out.println(p1.equals(p2)); // -- false

回答

equals()正在调用默认Object类的方法,该方法比较对象的标识*,即p1==p2,而不是其内容。这是equals来自的默认值Object

public boolean equals(Object obj) {
    return (this == obj);
}

如果要定义逻辑以确定两个Players 是否相等,则需要覆盖

  • equals() 方法
  • hashCode() 遵守equals-hash合约的方法

class Player {
    private String firstName;
    private String lastName;
    private double score;
    private double rating;

    // ...

    @Override
    public int hashCode() {
        return Objects.hash(firstName, lastName, score, rating);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null || getClass() != obj.getClass())
            return false;
        Player other = (Player) obj;
        return Objects.equals(firstName, other.firstName) && Objects.equals(lastName, other.lastName)
                && score == other.score && rating == other.rating;
    }

    // ...
}

Java SE 16

Java 16 Records功能可帮助您摆脱所有这些样板代码。上面提到的大部分仪式代码都可以自动提供给您,只需以下声明:

record Point(String firstName, String lastName, double score, double rating) { }

如果您想使用集合:

  • 实现 Comparable ——这不会让你直接比较,但对集合有用
  • 实施 Comparator

如果您想使用 Collections,例如为了能够排序,您可以实现该Comparable接口。这避免了破坏 equals 和 hashcode 契约,这是很难手动实现的

正如Holger评论的那样(他今天给我上了一课)当涉及基于数字的排序时使用它。

如果没有,您可以使用该Comparator接口。

在这个例子中,我使用的是 Comparable:

class Player implements Comparable<Player> 
{
   @Override
   public int compareTo(Player p2)  
   {
      /* Allows returning : (0)-> this==p2 | (1)-> this>p2 | (-1)-> this<p2
        Anyway, the meaning of 1 and -1 is up to you.
        if (this.name.equals(p2.name) && ...)
           return 0;
       else if ... 
            return 1;
       return -1;     */
   }
} 

* 感谢Henry Twist指出这一点。

  • To avoid breaking the equals and hashcode contract, you have to override the `hashCode` method. This is not even remotely related to implementing `Comparable`. In fact, you shouldn’t implement `Comparable` for things that don’t have a *natural order*. You can easily sort such objects using a dedicated `Comparator`, e.g. `Comparator.comparing(Person::getName)`. There are different ways to sort such objects and you can have different `Comparator`s. And, by the way, instead of `if(condition) return true; [else] return false;` you can simply write `return condition;`.

以上是如何比较类对象?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>