我正在阅读关于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
答案 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是指向链表的指针 包含键值对 哈希到同一个地方。抬头 需要扫描列表 使用给定键输入。插入 需要附加新的条目记录 到列表中的任何一端 哈希槽。删除需要 搜索列表并删除 元件。 (这项技术也被称为 开放散列或封闭寻址, 不应该混淆 '开放寻址'或'关闭 散列”。)
如果所谓的“专家”不能同意“开放散列”一词的含义,最好避免使用它。