1、Object類中默認(rèn)的實(shí)現(xiàn)方式是:return this == obj。也就是說,只有this和obj引用同一個(gè)對(duì)象的時(shí)候,才會(huì)返回true
2、equals方法需要滿足以下規(guī)則:
(1)、自反性:x.equals(x)應(yīng)該返回true;
(2)、對(duì)稱性: x.equals(y)為true,那么y.equals(x)也為true;
(3)、傳遞性:x.equals(y)為true,并且y.equals(z)為true,那么x.equals(z)也應(yīng)該為true;
(4)、 一致性: x.equals(y)的第一次調(diào)用為true,那么第二次、第三次、第n次調(diào)用也應(yīng)該為true,前提條件是在比較之前沒有修改x也沒有修改y;
(5)、對(duì)非空引用x, x.equals(null)返回false。
3、用一個(gè)demo簡(jiǎn)單介紹一下equals方法的編寫
public class EqualsDemo
{
private String name;
private int age;
public EqualsDemo()
{
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if ((obj == null) || (obj.getClass() != this.getClass()))
return false;
// 能執(zhí)行到這里,說明obj和this同類且非null。
EqualsDemo p = (EqualsDemo) obj;
return age == p.age && (name == p.name || (name != null && name.equals(p.name)));
}
@Override
public int hashCode()
{
// 重寫equals,也必須重寫hashCode。具體后面介紹。
}
}
EqualsDemo的對(duì)象有二個(gè)字段,name和age,這2個(gè)字段代表了對(duì)象的狀態(tài),也會(huì)用在equals方法中作為評(píng)判的依據(jù)。
在equals方法中,首先將obj(傳入對(duì)象的引用)和this做比較,節(jié)約執(zhí)行時(shí)間,如果this 和 obj是 對(duì)同一個(gè)堆對(duì)象的引用,那么,他們一定是相等的。
接著,判斷obj是否為null,如果是bull,一定不相等,因?yàn)榧热划?dāng)前對(duì)象this能調(diào)用equals方法,那么它一定不是null,非null和null當(dāng)然不相等。
然后,比較2個(gè)對(duì)象的運(yùn)行時(shí)類,是否為同一個(gè)類。不是同一個(gè)類,則不相等。getClass返回的是 this 和obj的運(yùn)行時(shí)類的引用。如果他們屬于同一個(gè)類,則返回的是同一個(gè)運(yùn)行時(shí)類的引用。注意,一個(gè)類也是一個(gè)對(duì)象。
也有人使用下面方法替代上面比較運(yùn)行時(shí)類的寫法,應(yīng)該避免這樣做:
if(!(obj instanceof EqualsDemo))
return false; // avoid 避免!
因?yàn)樗`反了規(guī)則中的對(duì)稱性,例如;假設(shè)Dog類擴(kuò)展了Animal類。這就會(huì)導(dǎo)致
animal.equls(dog) 返回true
dog.equals(animal) 返回false
僅當(dāng)EqualsDemo類沒有子類的時(shí)候,這樣做才能保證是正確的。
按照第一種方法實(shí)現(xiàn),那么equals只能比較同一個(gè)類的對(duì)象,不同類對(duì)象永遠(yuǎn)是false。但這并不是強(qiáng)制要求的。一般我們也很少需要在不同的類之間使用equals。
在具體比較對(duì)象的字段的時(shí)候,對(duì)于基本值類型的字段,直接用 == 來比較(注意浮點(diǎn)數(shù)的比較,這是一個(gè)坑)對(duì)于引用類型的字段,你可以調(diào)用他們的equals,當(dāng)然,你也需要處理字段為null 的情況。對(duì)于浮點(diǎn)數(shù)的比較,我在看Arrays.binarySearch的源代碼時(shí),發(fā)現(xiàn)了如下對(duì)于浮點(diǎn)數(shù)的比較的技巧:
if ( Double.doubleToLongBits(d1) == Double.doubleToLongBits(d2) ) //d1 和 d2 是double類型
if( Float.floatToIntBits(f1) == Float.floatToIntBits(f2) ) //f1 和 f2 是d2是float類型
并不總是要將對(duì)象的所有字段來作為equals 的評(píng)判依據(jù),那取決于你的業(yè)務(wù)要求。比如你要做一個(gè)家電功率統(tǒng)計(jì)系統(tǒng),如果2個(gè)家電的功率一樣,那就有足夠的依據(jù)認(rèn)為這2個(gè)家電對(duì)象等價(jià)了,至少在你這個(gè)業(yè)務(wù)邏輯背景下是等價(jià)的,并不關(guān)心他們的價(jià)錢啊,品牌啊,大小等其他參數(shù)。
最后需要注意的是,equals 方法的參數(shù)類型是Object,不要寫錯(cuò)!
注釋以上部分內(nèi)容來自:
lulipro
上一篇:ArrayList與LinkedList比較
下一篇:關(guān)于Object類的hashcode()方法的特點(diǎn)