甚至将长整数标识符分配到存储桶中

时间:2017-10-10 16:02:28

标签: java long-integer hashcode modulo uniform-distribution

我有一大组长整型标识符需要尽可能均匀地分配到(n)桶中。长整数标识符可能包含缺少标识符的口袋。 以此为标准,使用长整数和模数(n)[长整数]之间是否存在差异,或者为长整数的字符串版本生成hashCode更好(以改善分布)然后做一个modulo(n)[hash_code of string(long integer)]?是否需要额外的字符串转换才能通过哈希码获得统一传播?

由于我得到反馈,我的问题没有足够的背景信息。我正在添加更多信息。

标识符基本上是自动递增数字行标识符,这些标识符在表示项ID的数据库中自动生成。缺少标识符的原因是删除。

标识符本身是长整数。 标识符(项目)本身在某些情况下大约为(10s-100)+百万,在某些情况下大约为数千。

仅在标识符为数百万的情况下,我才真正将它们分散到存储桶(标识符计数>>存储桶计数)中,以便存储在无SQL系统(分区)中。

我想知道是否由于项目被删除的事实,我是否应该使用(Long).toString()。hashCode()来获得统一传播而不是直接使用长数字。我有一种感觉,做一个toString.hashCode不会给我带来太大的影响,而且我也不喜欢java hashCode不能保证java版本中的相同值(尽管对于String,他们的hashCode实现似乎有记录并且稳定过去几年的过去发布 )

2 个答案:

答案 0 :(得分:1)

无需涉及String

new Integer(i).hashCode()

...为您提供哈希 - 专为均匀分配到存储桶而设计。

new Integer(i).hashCode() % n

...会给你一个你想要的范围内的数字。

然而 Integer.hashCode()只是:

 return value;

因此new Integer(i).hashCode() % n相当于i % n

答案 1 :(得分:1)

您的问题无法回答。 @ slim的尝试是最好的,因为你的问题中缺少关键信息。

  • 要分发一组项目,您必须了解其初始分发情况。

如果它们均匀分布,则桶的数量明显高于输入的范围,那么苗条的答案就是要走的路。如果这些条件中的任何一个都不成立,那么它就不会起作用。

  • 如果输入范围没有明显高于存储桶数量,则需要确保输入范围是存储桶数量的精确倍数,否则最后的存储桶不会获得尽可能多的物品。例如,对于范围[0-999]和400个桶,前200个桶获得项[0-199],[400-599]和[800-999],而其他200个桶获得iems [200-399]和[200-99] 600-799]。

    也就是说,你的一半桶最多比另一半多50%。

  • 如果它们不是均匀分布的,因为模运算符除了包装之外不会改变分布,输出分布也不均匀。

    这是您需要哈希函数的时候。

    但是要构建哈希函数,您必须知道如何表征输入分布。哈希函数的要点是打破输入的重复,可预测的方面。

公平地说,有些哈希函数在大多数数据集上运行得相当好,例如Knuth的乘法方法(假设输入不太大)。你可以说,计算

hash(input) = input * 2654435761 % 2^32

擅长破坏价值集群。但是,它失败了。也就是说,如果您的大多数输入可以被2整除,那么输出也是如此。 [信用this answer]

我发现this gist有一个有趣的汇编,包含各种散列函数及其特征,你可以选择一个最符合数据集特征的函数。