我有两个对象列表,用户和产品
用户拥有产品,每个产品关联1个用户
但是一个产品类型可以有多个并且由不同的用户拥有
我需要为每个唯一的(用户+产品)生成一个ID
这可能不是一个好主意
user.hashCode() + product.hashCode()
什么是继续下去的好方法?
如果用户和产品都创建伪随机哈希代码,那么您的
hashCode
并没有那么糟糕。如果您担心由于 user
或 product
中的 hashCode 实现不当而导致哈希冲突,请将源哈希代码之一乘以素数:
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((product == null) ? 0 : product.hashCode());
result = prime * result + ((user == null) ? 0 : user.hashCode());
return result;
}
Eclipse 在选择 Source | 时构建了这段代码。生成 hashCode() 和 equals().
正如 Thilo 所提到的,您也可以简单地使用
Arrays.hashCode(new Object[]{ user, product })
;此调用负责处理用户或产品的 null
值,并将结果乘以 31 - 与手写代码相同。
如果您使用 Google Guava,有一个 Objects.hashCode(Object...)
可以使您的意图更加清晰并使用可变参数,但它也仅委托给 Arrays.hashCode
。
您可以让 Apache Commons HashCodeBuilder 为您完成这项工作。
它可以让你写类似的东西
return new HashCodeBuilder(17, 37).
append(user).
append(product).
toHashCode();
一个常见的解决方案是将第一个哈希值与素数相乘,然后添加第二个哈希值。
我们需要做两点:
我建议这样:
在数值上我们有这样的算法:
a = hash1
b = hash2
p = a+b
result_hash = p*(p+1)/2+b
但是如果我们减少算法,这不会影响碰撞:
a = hash1
b = hash2
p = a+b
result_hash = p*p+b
我们可以检查这个(在Python中):
N=256 # number of different values of hash
d = {}
for a in range(N):
for b in range(N):
p = a+b
x = (p*p+b)%N
if x in d:
d[x]+=1
else:
d[x]=1
print(max(v for k,v in d.items()))