簡體   English   中英

生成具有唯一整數的哈希碼

[英]generating hashcode with already unique integer

簡單的問題。 我有一個對象:

class User {

    int id;
    String username;

    public User() {
    }

    public User(int id, String username) {
        this.id = id;
        this.username = username;
    }

    @Override
    public String toString() {
        return id + " - " + username;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 31 * hash + this.id;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final User other = (User) obj;
        return this.id == other.id;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public int getId() {
        return id;
    }
}

根據int id (它是一個數據庫 id)確定誰的相等性。

Netbeans 自動生成了這個hashCode()方法:

@Override
public int hashCode() {
    int hash = 7;
    hash = 31 * hash + this.id;
    return hash;
}

問題是:與僅返回(已經)唯一的int id相比,這有什么優勢嗎?

@Override
public int hashCode() {
    return id;
}

無論哪種方式,碰撞都是不可能的。

對?

1)你可以這樣做:

@Override
public int hashCode() {
    return 1; // or any int constant here
}

2) 如果你說 1,000,000 個這樣的對象
數據庫,你也許可以做這樣的事情:

@Override
public int hashCode() {
    return id % 10000;
}

這樣,您將有 10000 個存儲桶用於 1,000,000 個對象。

3)您可以將id轉換為Integer然后執行以下操作:

@Override
public int hashCode() {
    return id.hashCode();
}

或等效於:

@Override
public int hashCode() {
    return id;
}

1) 和 3) 是 hashCode 實現的邊界情況。
方法 2) 處於中間位置。

Object.hashCode() javadoc告訴您回答問題所需知道的一切。

hashCode 的總合約為:

  • 在 Java 應用程序執行期間,只要在同一個對象上多次調用它,hashCode 方法必須始終返回相同的整數,前提是在對象的 equals 比較中使用的信息沒有被修改。 該整數不需要從應用程序的一次執行到同一應用程序的另一次執行保持一致。

  • 如果根據 equals(Object) 方法兩個對象相等,則對兩個對象中的每一個調用 hashCode 方法必須產生相同的整數結果。

  • 如果根據 equals(java.lang.Object) 方法兩個對象不相等,則不需要對兩個對象中的每一個調用 hashCode 方法必須產生不同的整數結果。 但是,程序員應該意識到為不相等的對象生成不同的整數結果可能會提高哈希表的性能。

id31 * 7 + id之間存在雙射,因此返回id是等效的。 因此,我會簡單地return id; 並刪除不必要的計算/復雜性。

但這會構成合規的哈希碼方法嗎? 讓我們回到javadoc:

hashCode 的總合約為:

  • 在 Java 應用程序執行期間,只要在同一個對象上多次調用它,hashCode 方法必須始終返回相同的整數,前提是在對象的 equals 比較中使用的信息沒有被修改。 該整數不需要從應用程序的一次執行到同一應用程序的另一次執行保持一致。
  • 如果根據 equals(Object) 方法兩個對象相等,則對兩個對象中的每一個調用 hashCode 方法必須產生相同的整數結果。
  • 如果根據 equals(java.lang.Object) 方法兩個對象不相等,則不需要對兩個對象中的每一個調用 hashCode 方法必須產生不同的整數結果。 但是,程序員應該意識到為不相等的對象生成不同的整數結果可能會提高哈希表的性能。

它適用於您的情況嗎?

  • (i) 希望滿意:您不會隨意更改給定對象的 id,對嗎?
  • (ii) 如果兩個用戶相等,他們有相同的哈希碼:是的,因為你的相等也是基於 id
  • (iii) 滿意

暫無
暫無

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

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