java哈希映射_java-如何在hashCode()中将long映射到int?

1024:(1024*1024)在大多数情况下是一个很好的哈希码; 特别是当长线分布均匀时。

由于它是公认的答案,因此我将发布此信息,以阐明我的一些评论,即长期以来它不是一个好的哈希码。

我给出的示例是这样的Point类:

public class Point {

private final long coords; //x in high-bits, y in low

public int getX() {

return (int)(coords >> 32);

}

public int getY() {

return (int)coords;

}

public int hashCode() {

return (int)((coords >> 32) ^ (coords));

}

}

它似乎是人为的,但有时您会将多个“字段”打包成一个长整型。

因此1024:(1024*1024)字段表示x的32位和y的32位。 那么为什么这是一个问题呢? 好吧,不是x和y中的每个均匀分布在它们各自的32位上。 但这在实践中不太可能。 X和Y更有可能被某个数字限制。 假设1024是2 ^ 10。 这意味着每个X和Y最多设置低10位:

00000000 00000000 000000XX XXXXXXXX 00000000 00000000 000000YY YYYYYYYY

有2 ^ 20(1024 * 1024)种可能的组合。 但是hashCode在做什么呢?

00000000 00000000 000000XX XXXXXXXX

^ 00000000 00000000 000000YY YYYYYYYY

-------------------------------------

= 00000000 00000000 000000?? ????????

最多有2 ^ 10(1024)个hashCode值,因为只有低10位可以是零以外的任何值。 哈希值与实值的比率为1024:(1024*1024)或1:1024。因此,马上就有两个数字具有相同哈希值的概率为1/1024。

现在让我们通过应用生日问题中的数学来计算发生碰撞的可能性。 令p(n)为具有n个值的至少一次碰撞的概率。 我们知道p(1025+)= 1,因为只有1024个值。

p(n) = 1 - (n! * (1024 choose n))/1024^n

这可以解决以下问题:

n: p(n)

1: 0.00000

2: 0.00098

3: 0.00293

4: 0.00585

5: 0.00973

6: 0.01457

...

38: 0.50096

...

79: 0.95444

...

148: 0.99999

只有38个项目,可能会发生碰撞。 拥有148件物品,有99.999%的机会(至少一次)碰撞。 共有148个项目,每个项目与另一个项目发生碰撞的机率为7%。 借助适当的哈希功能,了解域知识后,这些数字很容易降至0。

换句话说,了解您的领域以及实践中的情况是进行高效哈希的关键。 库函数会尽力在不了解您的域的情况下尽力而为,并且要想表现出色,通常要依靠实践中不会出现的数据分布。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值