Java中的“哈希表是开放的”是什么意思?

时间:2009-08-17 15:43:16

标签: java hashtable hash-collision

我正在阅读关于Hashtable类的Java api文档,并遇到了几个问题。在文档中,它显示“ Note that the hash table is open: in the case of a "hash collision", a single bucket stores multiple entries, which must be searched sequentially. ”我自己尝试了以下代码

Hashtable<String, Integer> me = new Hashtable<String, Integer>();
me.put("one", new Integer(1));
me.put("two", new Integer(2));
me.put("two", new Integer(3));
System.out.println(me.get("one"));  
System.out.println(me.get("two"));

输出是

1
3
  1. 这是“开放”的意思吗?
  2. 整数2发生了什么?收集为垃圾?
  3. 是否有“封闭”的例子?

6 个答案:

答案 0 :(得分:11)

不,这不是“开放”的含义。

请注意冲突与哈希冲突之间的区别。

Hashtable不允许多个条目具有相同的(在您的示例中,您使用键“two”放置两个条目,第二个(3)替换第一个(2),你只剩下Hashtable中的第二个。)

hash 冲突是指两个不同的密钥具有相同的哈希码(由hashCode()方法返回)。不同的哈希表实现可以以不同的方式对待它,主要是在低级实现方面。作为“开放”,Hashtable将存储其键复制到相同值的条目的链接列表。在最坏的情况下,这可能导致简单操作的O(N)性能,通常在哈希映射中为O(1),其中散列大多数是不同的值。

答案 1 :(得分:3)

这意味着具有相同哈希码的两个项目最终会出现在相同的存储区中。

在您的情况下,“两个”键是相同的,因此第二个键会覆盖第一个。

但假设你有自己的班级

class Thingy {
    private final String name;

    public Thingy(String name) {
         this.name = name;
    }

    public boolean equals(Object o) {
        ...

    }

    public int hashcode() {
       //not the worlds best idea
       return 1;
    }

}

并创建了它的多个实例。即。

Thingy a = new Thingy("a"); 
Thingy b = new Thingy("b"); 
Thingy c = new Thingy("c"); 

将它们插入地图中。然后一个桶,即包含具有哈希码1的东西的桶将包含三个项目的列表(链)。

Map<Thingy, Thingy> map = new HashMap<Thingy, Thingy>();
map.put(a, a);
map.put(b, b);
map.put(c, c);

因此,通过任何Thingy键获取项目将导致查找哈希码O(1),然后在存储桶中具有哈希码1的项目列表上进行线性搜索O(n)。

在实现hashcode和equals时,还要注意确保遵循正确的关系。即,如果两个对象相等,那么它们应该具有相同的hascode,但不一定是另一回事,因为多个键可能会获得相同的哈希码。

哦,对于Open哈希和Closed哈希表的完整定义,请查看http://www.c2.com/cgi/wiki?HashTable

答案 2 :(得分:2)

这意味着Hashtable使用open hashing(也称为单独链接)来处理哈希冲突。如果两个单独的密钥具有相同的哈希码,则它们都将存储在同一个存储桶中(在列表中)。

答案 3 :(得分:2)

打开意味着如果两个键不相等但具有相同的哈希值,则它们将存储在同一个“桶”中。在这种情况下,您可以将每个存储桶视为链接列表,因此如果在同一存储桶中存储了许多内容,搜索性能将会降低。

Bucket 0:什么都没有 铲斗1:项目1
铲斗2:项目2 - &gt;第3项 斗3:什么都没有 第4栏:第4项

在这种情况下,如果搜索散列到存储桶2的密钥,则必须在列表上执行O(n)搜索,以找到与您要搜索的内容相等的密钥。如果键哈希到Bucket 0,1,3或4,那么您将获得O(1)搜索性能。

答案 4 :(得分:1)

哈希是一个计算函数,它将一个对象(样本中的“一个”或“两个”)映射到(在本例中)一个整数。这意味着可能有多个值映射到同一个整数(整数具有有限数量的允许值,而可能有无限数量的输入)。在这种情况下,“等于”必须能够将这两者分开。所以你的代码示例是正确的,但可能有一些其他密钥具有相同的哈希码(并将与“两个”放在同一个桶中)

答案 5 :(得分:1)

警告:常见用法中存在“开放哈希”的矛盾定义:

引自另一个答案中引用的http://www.c2.com/cgi/wiki?HashTable

  

警告:有些人使用这个词   “开放哈希”意味着我的意思   这里叫“封闭哈希”!该   这里的用法与此一致   在TheArtOfComputerProgramming和   IntroductionToAlgorithms,两者都有   如果是推荐参考   你想进一步了解哈希   表。

例如,上面的页面定义了“open hashing”,如下所示:

  

主要有两种策略。 打开   散列,也称为开放寻址,   说:当你输入表格时   对于新的键/值对已经存在   占用,找到另一个未使用的条目   不知怎的,把它放在那里。关闭   哈希说:表中的每个条目   是一种辅助数据结构(通常是   一个链表,但还有其他   可能性)包含实际   数据,这个数据结构可以   延伸无限制。

相比之下,Wikipedia提供的定义是:

  

在称为独立的策略中   链接,直接链接,或简单   链接,桶的每个槽   array是指向链表的指针   包含键值对   哈希到同一个地方。抬头   需要扫描列表   使用给定键输入。插入   需要附加新的条目记录   到列表中的任何一端   哈希槽。删除需要   搜索列表并删除   元件。 (这项技术也被称为   开放散列或封闭寻址,   不应该混淆   '开放寻址'或'关闭   散列”。

如果所谓的“专家”不能同意“开放散列”一词的含义,最好避免使用它。