Java 如何获得哈希表中使用的最佳数字?

Java 如何获得哈希表中使用的最佳数字?,java,math,data-structures,hashtable,Java,Math,Data Structures,Hashtable,正如问题所述,如何计算使用的最佳数量以及如何激励它 如果我们要构建一个使用以下哈希函数的哈希表: h(k)=k模m,k=键 所以一些消息来源告诉我: 使用要插入的元素数作为m的值 使用接近m的素数 java只是使用31作为m的值 有人告诉我用闭素数,2^n作为m 在这一点上我很困惑,我不知道m应该使用什么值。比如说,如果我们用表的大小来表示m,那么如果我们想扩展表的大小,会发生什么呢?然后我必须用新的值m来重新灰化所有的值。如果是这样,为什么Java只使用31作为m的素数 我还听说,表的大小应该

正如问题所述,如何计算使用的最佳数量以及如何激励它

如果我们要构建一个使用以下哈希函数的哈希表:

h(k)=k模m,k=键

所以一些消息来源告诉我:

  • 使用要插入的元素数作为m的值
  • 使用接近m的素数
  • java只是使用31作为m的值
  • 有人告诉我用闭素数,2^n作为m
  • 在这一点上我很困惑,我不知道m应该使用什么值。比如说,如果我们用表的大小来表示m,那么如果我们想扩展表的大小,会发生什么呢?然后我必须用新的值m来重新灰化所有的值。如果是这样,为什么Java只使用31作为m的素数

    我还听说,表的大小应该是哈希表中元素总数的两倍,也就是说,每次它重新灰化时。但是我们为什么要用m=10来表示一个包含10个元素的表,而它应该是m=20来创建额外的空空间呢

    有人可以帮助我理解如何根据不同的场景计算m的值,比如我们想要一个静态(我们知道我们只需要输入10个元素)或动态(在一定限制后重新设置)哈希表

    让我们通过以下示例来说明我的问题: 我得到了值{1,2,…,n}

    问:如果我必须在hashfunction中使用除以mod,那么m的优化值是多少

    Senario 1:n=100?

    Senario 2:n=5043?

    添加问题: 如果我们使用开放或封闭的哈希表,m值哈希函数会有所不同吗

    请注意,我现在不需要了解java的hashtable,而需要了解hashtable,在这里我必须使用division mod hashtable函数


    谢谢你抽出时间

    这里有几个问题: 1) 我应该平等些什么? 2) 哈希表中应该有多少可用空间? 3) 您是否应该将表的大小设置为素数

    1) 正如在评论中提到的,您描述的h(k)不是散列函数,它为您提供散列表的索引。其思想是每个对象都会产生一些哈希代码,这是一个正整数。您可以使用哈希代码来确定将对象放在哈希表中的位置(以便以后可以再次找到它)。很明显,您不想要大小为MAX_INT的哈希表,所以选择一些大小为m的哈希表。然后对于任何对象,取其哈希代码,计算k%m,现在在区间[0,m-1]中有一个整数,它是哈希表中的有效索引

    2) 由于哈希表的工作原理是使用哈希代码在表中查找对象应放在的位置,因此如果将多个项分配到同一位置,则会遇到麻烦。这叫做碰撞。每个哈希表实现都必须处理冲突,要么将项目放在附近的位置,要么在每个位置保留项目的链接列表。无论采用何种解决方案,冲突越多,哈希表的性能就越低。因此,建议您不要让哈希表填满,否则,冲突的可能性更大。保持哈希表至少是项目数的两倍是减少冲突概率的常见建议。显然,这意味着您必须在表格填满时调整其大小。是的,这意味着您必须重新灰化每个项目,因为当您以不同的值获取模数时,它将进入不同的位置。这就是哈希表的隐藏成本:它在固定时间内运行(假设很少或没有冲突),但它可以有一个较大的系数(氨化的大小调整、重新灰化等)


    3) 通常还建议将哈希表的大小设置为素数。这是因为在某些常见用例中,它倾向于在哈希表中生成更好的项分布,从而避免冲突。我不会在这里给出完整的解释,而是让您参考这个极好的答案:

    Java通过重写
    hashCode
    来使用您告诉它的任何东西。典型的习惯用法是在组合单个对象属性的hashcode时使用31的迭代乘法,并且根本不使用模。是的,这回答了这个问题,但是如果我们在hashfunction和mod的除法的上下文中对其进行更一般化,会怎么样。31是n<31的理想素数吗?如果是的话,如果n的大小大于31怎么办?哈希函数本身与哈希表的大小无关。其主要可取的特点是,它很好地分散了价值观。请注意,在Java中,哈希函数属于键对象,而哈希表大小显然封装在一个完全不同的独立类中。您无法针对特定的哈希表大小优化哈希代码。除非您的键是整数,否则您的
    h(k)
    不是哈希函数(或者根本不是任何函数-它只是格式不正确)。相反,它看起来像是将哈希值转换为表索引的代码。那么m是表的大小。