2010-10-20 37 views
3

现在,我想了解如何构建Hashtable哈希表。怎么运行的?

最有趣的 - 作为对象被添加到Hashtable

我曾在一本书,上面写着:

在第一步: 计算hashCode()对象。

接下来,我们确定此对象在Hashtableobj.hashCode() % Hashtable.length中的位置。

例如,加入更多的元素到Hashtable

Hashtable<String, String> hm=new Hashtable<String, String>(100); 

     hm.put("Lee","Lee"); 
     hm.put("lee","lee"); 
     hm.put("eel","eel"); 

定义成被放置在对象的铲斗:

System.out.println("Lee".hashCode() % 100); 
    System.out.println("lee".hashCode() % 100); 
    System.out.println("eel".hashCode() % 100); 

如果我理解该算法,对象必须放置在该表如下:

eel /*because,"eel".hashCode() % 100=0*/, 
lee /*because, "lee".hashCode() % 100=20*/, 
Lee /*because, "Lee".hashCode() % 100=68*/ 

但我们所看到的结果?

System.out.println(hm); 

{Lee=Lee, lee=lee, eel=eel} 

请告诉我,我哪里出错了?

回答

7

Hashtable(以及HashMap)元素的迭代顺序不能保证(依赖于实现),所以恕我直言,没有太多的尝试在它上面建立理论。它甚至可能在不同的Java版本之间改变(它从Java5改为Java6)。

btw Hashtable已过时,建议使用(并分析)HashMap来代替。

你的描述对我来说听起来还不错,作为一个基本的哈希映射实现。然而,HashMap的实际实现比这更加复杂,至少从Java4开始。例如。散列表的大小始终是2的幂(对于像你所描述的基本散列表,这将是一个相当糟糕的决定),并且从关键对象获得的散列值在内部被重新映射以实现对实际大小的更均匀分布的表格。有关更多细节,请参见Java专家通讯的以下问题:

+1

+1“在Perl中,它甚至在程序调用之间改变,以防止使用散列冲突的拒绝服务攻击。 – Thilo 2010-10-20 07:48:03

+0

一个额外的散列函数,以防止碰到同一个桶中的不同密钥。 – 2010-10-20 07:54:52

2

一个Hashtable是从键到值的映射。当您打印一个Hashtable时会显示这个映射。

有关.hashCode.equals的故事粗略描述了它如何在内部跟踪键/值对。

对你的问题的一些言论虽然:

  • 您在例如设置为100 capacity并不代表桶存储中的对象的数量,代表对象的数量。 Hashtable具有容量,负载因子为0.75。

  • 桶的数量在运行时期间可能会有所不同。如果持续添加对象很长时间,则加载因子将会增加,并且可能会重新分配存储桶并将对象“重新加入”。

From the docs

加载因子是哈希表是如何充分允许才把它容量自动增加措施。初始容量和负载因子参数为仅仅暗示实施。有关何时以及是否调用rehash方法的确切细节是依赖于实现的

1

哈希表的概念是根据一些哈希函数(取对象并返回索引)将对象添加到表中。

你对散列表的描述只是许多(许多...)中的一个,如果它是用Java以与你读的相同的方式实现的,我会感到惊讶。

0

正如之前所提到的,Hashtable是依赖于实现的,我会建议阅读一般的Hashtable,以了解它们是如何工作的,然后理解它如何工作以阅读Java或其他语言中的特定实现。

Wikipedia在这个话题上有相当不错的文章,所以我建议先阅读。 “它可能甚至会在不同的Java版本之间发生变化”