[從 Effective Java 了解 Kotlin] 覆寫 equals 以及 hashCode 方法

Item 10 — Obey the general contract when overriding equals

equals()

public class Player {
private final String name;
private final int number;
public Player(String name, int number) {
this.name = name;
this.number = number;
}
}
final Player jordan1 = new Player("Jordan", 23);
final Player jordan2 = new Player("Jordan", 23);
final Player jordan1_clone = jordan1;
System.out.println(jordan1.equals(jordan2));
System.out.println(jordan1.equals(jordan1_clone));
false
true
class PlayerK(private val name: String, private val number: Int)fun main() {
val jordan1 = PlayerK("Jordan", 23)
val jordan2 = PlayerK("Jordan", 23)
val jordan1_clone = jordan1
println(jordan1 == jordan2)
println(jordan1 == jordan1_clone)
}
false
true

在 Kotlin 中,資料類別 (data class) 是我們的好朋友,當我們想要把資料儲存在類別裡,又不希望自行覆寫 equals() 時,就可以選用資料類別。

Java 14 也推出了相同作用的紀錄類別 (record class)。

那麼,如果我們想要自行覆寫 equals() 呢?我們該怎麼做呢?

筆者使用 IntelliJ IDEA 嘗試覆寫 Java 的 equals() 的函式時,發現 IntelliJ IDEA 會自動幫忙產生 equals() 以及 hashCode() ,超方便的。

public class Player{
...
@Override
public boolean equals(Object o) {
if (this == o) return true; // 1
if (!(o instanceof Player)) return false; // 2
Player player = (Player) o; // 3-1
return number == player.number && Objects.equals(name, player.name); // 3-2
}
@Override
public int hashCode() {
return Objects.hash(name, number);
}
}

通用規範 (general contract)

我們再回到自動產生的 equals()

@Override
public boolean equals(Object o) {
if (this == o) return true; // 1
if (!(o instanceof Player)) return false; // 2
Player player = (Player) o; // 3-1
return number == player.number && Objects.equals(name, player.name); // 3-2
}
public class BaseballPlayer extends Player{
final String position;

public BaseballPlayer(String name, int number, String position) {
super(name, number);
this.position = position;
}
}

Item 11 — Always override hashcode when you override equals

小結

--

--

Android/Flutter developer, like to learn and share.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store