第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

在繼承層次結(jié)構(gòu)中實(shí)現(xiàn)健壯的 equals() 和 hashCode() 方法的正確方法是什么?

在繼承層次結(jié)構(gòu)中實(shí)現(xiàn)健壯的 equals() 和 hashCode() 方法的正確方法是什么?

米琪卡哇伊 2022-01-19 17:09:13
我有以下抽象Person類:import java.util.Objects;public abstract class Person {    protected String name;    protected int id;    public Person(String name, int id) {        this.name = name;        this.id = id;    }    public abstract String description();    @Override    public boolean equals(Object obj) {        if(this == obj) return true;        if(!(obj instanceof Person)) return false;        return Objects.equals(this.name, ((Person) obj).name) &&                this.id == ((Person) obj).id;    }    @Override    public int hashCode() {        return Objects.hash(this.name, this.id);    }}現(xiàn)在我有一個(gè)Person名為的子類Employee:import java.time.LocalDate;import java.util.Objects;public class Employee extends Person {    private double salary;    private LocalDate hireDay;    public Employee(String name, int id, double salary, int year, int month, int day) {        super(name, id);        this.salary = salary;        this.hireDay = LocalDate.of(year, month, day);    }    @Override    public String description() {        return "Employee with a salary of " + this.salary;    }    @Override    public int hashCode() {        return super.hashCode() + Objects.hash(this.salary,this.hireDay);    }}要正確實(shí)現(xiàn) equals 方法,它必須符合以下約定。自反式:x.equals(x) 始終為真對(duì)稱式:x.equals(y) 等價(jià)于 y.equals(x)傳遞式:x.equals(y) 和 y.equals(z) 蘊(yùn)含 x.equals(z)是真的當(dāng)我在子類內(nèi)部調(diào)用超類的equals()方法時(shí),我首先確保所有被比較的對(duì)象都是超類的子類。這個(gè)問題解決了比較混合類型的問題,并照顧了上面提到的合同。我不再需要使用以下 equals 實(shí)現(xiàn):也就是說,我不再需要顯式檢查當(dāng)前對(duì)象 ( ) 是否與使用運(yùn)算符的超類中的方法this屬于同一類。objinstance of將該實(shí)現(xiàn)放在超類的equals運(yùn)算符中是否更健壯,或者使用該getClass()方法在子類中使用更明確的測(cè)試以符合合同更好?就 hashCode() 方法而言,我對(duì)特定于子類的私有實(shí)例字段進(jìn)行哈希處理,然后簡(jiǎn)單地將其添加到超類中哈希方法的結(jié)果中。我找不到任何文檔來說明這是否是實(shí)現(xiàn) hashCode() 函數(shù)的正確方法,或者在繼承層次結(jié)構(gòu)中。我見過人們明確指定自己的哈希函數(shù)的代碼。如果我的問題過于籠統(tǒng),我深表歉意,但我盡我所能地問他們,但不會(huì)太模棱兩可。編輯:我要求 Intellij 實(shí)現(xiàn)一個(gè) equals 和 hashcode 方法,它決定使用我上面發(fā)布的最后一個(gè)實(shí)現(xiàn)。那么,在什么情況下我會(huì)instance of在超類中使用呢?當(dāng)我在超類中實(shí)現(xiàn)最終的equals方法時(shí)會(huì)不會(huì)是這樣,例如僅根據(jù)用戶ID比較Person對(duì)象?
查看完整描述

3 回答

?
qq_花開花謝_0

TA貢獻(xiàn)1835條經(jīng)驗(yàn) 獲得超7個(gè)贊

以下是我在閱讀 Effective Java 2nd Edition 時(shí)的筆記:

Equals 必須遵守一般合同:

  • 反身的:對(duì)于non-null xx.equals(x) == true

  • 對(duì)稱:對(duì)于non-null x,yx.equals(y) <==> y.equals(x)

  • 傳遞:對(duì)于non-null x,y,zx.equals(y) and y.equals(z) ==> x.equals(z) == true

  • 一致:對(duì)于任何非空 x,y: if x.equals(y) == true,如果xy

  • 空:對(duì)于非空xx.equals(null) == false

高質(zhì)量等于方法:

  1. 使用 == 檢查參數(shù)是否是對(duì)該對(duì)象的引用 ( x == x)

  2. 使用 instanceof 檢查參數(shù)是否是正確的類型(也檢查null

  3. 將參數(shù)轉(zhuǎn)換為正確的類型

  4. 對(duì)于類中的每個(gè)“重要”字段,檢查參數(shù)的該字段是否與該對(duì)象的相應(yīng)字段匹配

  5. 完成后,檢查是否對(duì)稱、傳遞和一致

最后的警告:

  • 覆蓋 equals 時(shí)始終覆蓋 hashCode

  • 不要試圖太聰明

  • 不要在 equals 聲明中用其他類型替換 Object -> 不值得為了增加復(fù)雜性而獲得輕微的性能提升

來自 Effective Java 2nd Edition 的Hashcode直接引用

  1. 在名為 result 的 int 變量中存儲(chǔ)一些常量非零值,例如 17。

  2. 對(duì)于f對(duì)象中的每個(gè)重要字段(即 equals 方法考慮的每個(gè)字段),請(qǐng)執(zhí)行以下操作:

    • 計(jì)算字段的 int 哈希碼 c:

    • 將步驟 2.a 中計(jì)算的哈希碼 c 合并到結(jié)果中,如下所示: result = 31 * result + c;

    1. 如果該字段是布爾值,則計(jì)算(f ? 1 : 0).

    2. 如果該字段是 byte, char, short, or int, compute (int) f.

    3. 如果該字段是 long, compute (int) (f ^ (f >>> 32)).

    4. 如果該字段是 float, compute Float.floatToIntBits(f).

    5. 如果字段是 a double, compute Double.doubleToLongBits(f),則對(duì)結(jié)果進(jìn)行哈希處理long。

    6. 如果該字段是對(duì)象引用并且此類的 equals 方法通過遞歸調(diào)用比較該字段,則在該字段上equals遞歸調(diào)用hashCode。如果需要更復(fù)雜的比較,請(qǐng)為此字段計(jì)算“規(guī)范表示”并在規(guī)范表示上調(diào)用 hashCode。如果字段的值為nullreturn 0(或其他一些常數(shù),但 0 是傳統(tǒng)的)。

    7. 如果該字段是一個(gè)數(shù)組,則將其視為每個(gè)元素都是一個(gè)單獨(dú)的字段。也就是說,通過遞歸應(yīng)用這些規(guī)則來計(jì)算每個(gè)重要元素的哈希碼,并在步驟 2.b 中組合這些值。如果數(shù)組字段中的每個(gè)元素都很重要,則可以使用 1.5 版中添加的 Arrays.hashCode 方法之一。

  3. 返回結(jié)果。

  4. 當(dāng)你寫完 hashCode 方法后,問問自己相等的實(shí)例是否有相等的哈希碼。編寫單元測(cè)試來驗(yàn)證你的直覺!

所以遵循這些規(guī)則:

@Override

public boolean equals(Object obj) {


    if (this == obj) {

        return true;

    }


    if (!(obj instanceof Employee)) {

        return false;

    }

    Employee other = (Employee) obj;


    return super.equals(other) &&

           Double.compare(this.salary, other.salary) == 0 &&

           this.hireDay.equals(other.hireDay);


}

在您的情況下,雖然它似乎id應(yīng)該已經(jīng)唯一地標(biāo)識(shí)任何人,所以您應(yīng)該只使用它進(jìn)行比較,而不是在任何子類中覆蓋它。


查看完整回答
反對(duì) 回復(fù) 2022-01-19
?
飲歌長(zhǎng)嘯

TA貢獻(xiàn)1951條經(jīng)驗(yàn) 獲得超3個(gè)贊

如果你想實(shí)現(xiàn) equals 和 hashcode 方法使用 eclipse 只需右鍵單擊文件轉(zhuǎn)到源并選擇 generate equals() & hashcode() 和你需要的字段,如下所示:

http://img1.sycdn.imooc.com//61e7d56f000125cc13640766.jpg

http://img1.sycdn.imooc.com//61e7d57700018bf013630770.jpg


查看完整回答
反對(duì) 回復(fù) 2022-01-19
?
陪伴而非守候

TA貢獻(xiàn)1757條經(jīng)驗(yàn) 獲得超8個(gè)贊

兩個(gè)人有沒有可能永遠(yuǎn)一樣id?它不應(yīng)該。所以邏輯延伸到Employee類,這意味著在類中實(shí)現(xiàn)equals和就足夠了。hashCodePerson

此時(shí),由于您只處理一個(gè)int,您可以使用Integer.hashCode(id)forhashCode并僅比較 的值equals。


查看完整回答
反對(duì) 回復(fù) 2022-01-19
  • 3 回答
  • 0 關(guān)注
  • 185 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)