簡體   English   中英

哈希碼和等於實現

[英]Hashcode & equals implementation

我正在編寫一些代碼來演示equals和hashcode,對於我的實現,我使用了User示例:

public class User {
    private String name;
    private String pass;
    //...
    @Override
    public boolean equals(Object obj) {
        if (obj == null) { return false; }
        if (obj == this) { return true; }
        if (obj.getClass() != this.getClass()) {
            return false;
        }
        User rhs = (User) obj;

        EqualsBuilder eb = new EqualsBuilder();
        eb.append(this.getName(), rhs.getName());
        //eb.append(this.getPass(), rhs.getPass());
        return eb.isEquals();
    }
    @Override
    public int hashCode() {
        HashCodeBuilder hcb = new HashCodeBuilder(17, 37);
        hcb.append(this.getName());
        hcb.append(this.getPass());
        return hcb.toHashCode();
    }
    //...
    public static void main(String[] args) {

        User u1 = new User("foo","foo1");
        User u2 = new User("bar","bar1");
        System.out.println(u1.equals(u2));
        System.out.println(u1.hashCode() + " ?= " + u2.hashCode());
        User u3 = new User("foo","foo1");
        User u4 = new User("foo","bar1");
        System.out.println(u3.equals(u4));
        System.out.println(u3.hashCode() + " ?= " + u4.hashCode());

    }
}

輸出:

false
2128613651 ?= 2129111967
true
2128615478 ?= 2214545177

我想我做錯了,因為我的對象現在可以相等但具有不同的哈希碼(我知道這很糟糕),但是我想僅當用戶名也相等時才使用戶相等。名稱AND通行證等於。

我如何才能遵守這些約定,並實現自己的目標? 感謝您的幫助/說明:)

一般而言,如果equals()方法中不存在字段,則不應在hashCode()方法中引用該字段。

這樣可以確保您的hashcode()結果不會比equals()結果更頻繁地更改。 考慮將您的方法更改為:

@Override
public int hashCode() {
    HashCodeBuilder hcb = new HashCodeBuilder(17, 37);
    hcb.append(this.getName());
    return hcb.toHashCode();
}

話雖如此,創建一個非直覺的equals()方法很少是一個好主意。 我自然會假設您的方法也將考慮密碼,因為您將來的許多維護者也會考慮。 如果不進行真正的相等性測試,則單元測試可能很難編寫。 考慮創建自己的方法是否更好,例如

public boolean usernameEquals(User other) {
  ...
}

所有相等的對象具有相同的哈希碼。 但並非所有具有相同哈希碼的對象都是相等的。

您在hascode方法中使用的所有字段都應在equals方法中使用。

我不會說你做錯了。 就合同而言, 如果2個對象相等,則它們應具有相同的hashCode。 如果2個對象具有相同的hashCode,則它們不必相等

如果將2個User實例的相等性定義為- 它們相等,則如果它們的名稱相等 ,那么您就可以了。 就hashCodes而言,您是對的,因為如果2個對象的hashCodes不相等,則這些對象也不相等。

BTW Duncan完全正確地指出, 創建非直觀的equals()方法很少是一個好主意

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM