在添加几个小数字之后向HashSet添加一个大数字:会发生什么?

问题描述

我正在学习HashSet-s,但我不太了解它们如何构建表。我读过的每一篇文章都谈论%哈希集函数,这似乎意味着我应该向HasSet中添加几个小数字(int)(例如1、7、14),然后添加一个大数字(例如2732780)-该表用于HashSet将立即增长为无数单元格的巨大规模。我对么?如果不是,那么数字/元素以什么形式存储?在哪里可以详细了解?

更新:所以要澄清一下: 说我的哈希函数是x =(input / 10),y =(input%10),这意味着在上面的示例中,当您添加1、7和14时,HashSet会像这样构建表:

enter image description here

问题是,如果添加2732780,会发生什么?桌子应该爆炸了吧?还有大量的空数字吗?

解决方法

哈希集使用一个哈希函数。这会将任何数据类型转换为int。然后将此int放入存储桶中。这是通过将%与可用存储区的数量一起使用来完成的。

说它是x % 10。然后看起来像这样:

|input   |hashcode    |bucket
|1       |     1      |1
|7       |     7      |7
|14      |     14     |4
|2732780 |    2732780 |0

如果有两个条目具有相同的存储桶,则将保留一个列表,并且该存储桶中的查找是线性的。该实施将根据需要增加存储桶。

请参见https://docs.microsoft.com/en-us/dotnet/api/system.object.gethashcode?view=netcore-3.1#System_Object_GetHashCode

,

在Java中,HashSet是使用HashMap实现的(从算法的角度来看,在C#中没有理由不应该这样做)。

本文介绍了HashMap如何很好地工作: https://www.geeksforgeeks.org/internal-working-of-hashmap-java/

关键是要有地图容量的概念。这是保存地图存储区的数组。选择哪个索引的计算是:

index = hashCode(key)&(n-1)

,n为容量。这意味着,当您在set / map中插入更多条目时,实现将不断增长并重新哈希其条目。