如何比较类对象?
我想比较两个对象。但是,它告诉我当我运行它时它们不匹配,即使它们匹配。请让我知道我做错了什么,谢谢。这是我的代码:
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;`.