equals 方法
equals
方法需要滿足的規范:
- 自反性: 對於任意非空引用 x,
x.equals(x)
應該返回true
; - 對稱性: 對於任意引用, 當且僅當
x.equals(y) == true
時,y.equals(x) == true
; - 傳遞性: 對於任意引用 x/y/z, 如果
x.equals(y) == true
和y.equals(z) == true
, 則x.equals(z) == true
; - 對於任意非空引用 x,
x.equals(null) == false
;
編寫 equals()
方法的建議:
- 添加
@Override
注解, 重載父類Object.equals(Object)
方法; - 參數為
Object otherObject
, 稍后需要將它轉換成另一個叫做other
的變量; - 檢測
this
與otherObject
是否引用同一個對象; - 檢測
otherObject
是否為null
, 如果為null
, 返回false
; - 比較
this
與otherObject
是否屬於同一個類.
如果equals
的語義在每個子類中有所改變, 那就要使用getClass
檢測; - 將
otherObject
轉換為響應的類型變量other
; - 對所有需要比較的域進行比較, 使用
==
比較基本類型域, 使用equals
比較對象域. 如果所有的域都匹配, 就返回true
, 否則返回false
; - 如果在子類中重新定義了
equals
, 就要在其中調用super.equals(otherObject)
, 如果返回ture
, 則繼續比較子類特有的域.
在比較兩個對象是否相等時, 可使用 Objects.equals()
方法.
例如對於 Objects.equals(a, b)
:
- 當兩個參數都為 null 時, 返回
ture
; - 當其中一個參數為 null 時, 返回
false
; - 當兩個參數都不為 null 時, 返回
a.equals(b)
的返回值.
hashCode 方法
如果重新定義了 equals
方法, 就必須重新定義 hashCode
方法, 以便用戶將對象插入到散列表中.
hashCode
方法應該返回一個整型數值(也可以是負數), 並合理地組織實例域的散列碼, 以便能夠讓哥哥不同的對象產生的散列碼更加均勻.
Objects.hash(Object.. value)
可以傳遞多個參數並據此產生序列碼.
示例代碼:
import java.util.Objects;
public class TestEqualsAndHashCode {
private Object obj;
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
@Override
public boolean equals(Object otherObject) {
if (this == otherObject) {
return true;
}
if (null == otherObject) {
return false;
}
if (getClass() != otherObject.getClass()) {
return false;
}
TestEqualsAndHashCode other = (TestEqualsAndHashCode) otherObject;
return Objects.equals(getObj(), other.getObj());
}
@Override
public int hashCode() {
return Objects.hash(obj);
}
public static void main(String[] args) {
TestEqualsAndHashCode a = new TestEqualsAndHashCode();
TestEqualsAndHashCode b = new TestEqualsAndHashCode();
a.setObj(1);
b.setObj(1);
System.out.println(Objects.equals(a, b));
System.out.println(a.hashCode());
System.out.println(b.hashCode());
}
}