生成具有唯一整数的哈希码

时间:2014-03-31 21:29:25

标签: java hashcode hash-code-uniqueness

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

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

无论如何都不可能发生碰撞。

右?

3 个答案:

答案 0 :(得分:1)

1)你可以这样做:

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

2) 如果你在说明中有1,000,000个这样的对象 DB,你可能会做类似的事情:

@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)位于中间的某个地方。

答案 1 :(得分:1)

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

  

hashCode的一般合约是:

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

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

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

  •   

答案 2 :(得分: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)表示满意