我想比较两个对象。但是,它告诉我当我运行它时它们不匹配,即使它们匹配。请让我知道我做错了什么,谢谢。这是我的代码:
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
Run Code Online (Sandbox Code Playgroud)
您equals()正在调用默认Object类的方法,该方法比较对象的标识*,即p1==p2,而不是其内容。这是equals来自的默认值Object:
public boolean equals(Object obj) {
return (this == obj);
}
Run Code Online (Sandbox Code Playgroud)
如果要定义逻辑以确定两个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;
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
Java 16 Records功能可帮助您摆脱所有这些样板代码。上面提到的大部分仪式代码都可以自动提供给您,只需以下声明:
record Point(String firstName, String lastName, double score, double rating) { }
Run Code Online (Sandbox Code Playgroud)
如果您想使用集合:
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; */
}
}
Run Code Online (Sandbox Code Playgroud)
* 感谢Henry Twist指出这一点。