2

简单的问题。我有一个对象:

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;
}

问题是:与仅返回(已经) unique 相比,这有什么优势int id吗?

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

无论哪种方式,碰撞都是不可能的。

正确的?

4

3 回答 3

1

1)你可以这样做:

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

2) 如果您在数据库中有 1,000,000 个这样的对象
,您可能会执行以下操作:

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

这样,您将拥有 1,000,000 个对象的 10000 个存储桶。

3)你可以id变成一个Integer并这样做:

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

或等效的:

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

1) 和 3) 是 hashCode 实现的边界情况。
方法 2) 位于中间的某个位置。

于 2014-03-31T21:32:37.790 回答
1

Object.hashCode() javadoc告诉您回答问题所需知道的一切。

hashCode 的一般合约是:

  • 每当在 Java 应用程序执行期间对同一个对象多次调用它时,hashCode 方法必须始终返回相同的整数,前提是没有修改对象上的 equals 比较中使用的信息。该整数不需要从应用程序的一次执行到同一应用程序的另一次执行保持一致。

  • 如果两个对象根据 equals(Object) 方法相等,则对两个对象中的每一个调用 hashCode 方法必须产生相同的整数结果。

  • 如果根据 equals(java.lang.Object) 方法,如果两个对象不相等,则不需要对两个对象中的每一个调用 hashCode 方法都必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。

于 2014-03-31T21:33:09.987 回答
0

和之间存在双射id31 * 7 + id因此返回id是等价的。因此,我会简单地return id;删除不必要的计算/复杂性。

但这会构成一个兼容的哈希码方法吗?让我们回到 javadoc:

hashCode 的一般合约是:

  • 每当在 Java 应用程序执行期间对同一个对象多次调用它时,hashCode 方法必须始终返回相同的整数,前提是没有修改对象上的 equals 比较中使用的信息。该整数不需要从应用程序的一次执行到同一应用程序的另一次执行保持一致。
  • 如果两个对象根据 equals(Object) 方法相等,则对两个对象中的每一个调用 hashCode 方法必须产生相同的整数结果。
  • 如果根据 equals(java.lang.Object) 方法,如果两个对象不相等,则不需要对两个对象中的每一个调用 hashCode 方法都必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。

它适用于你的情况吗?

  • (i) 希望满意:您不会随意更改给定对象的 id,对吗?
  • (ii) 如果两个用户相等,他们具有相同的哈希码:是的,因为您的相等也是基于 id
  • (iii) 满意
于 2014-03-31T21:33:10.197 回答