双向哈希表






2.70/5 (7投票s)
2003年9月1日
2分钟阅读

76279

794
演示了一个易于使用的双向哈希表,以方便反向查找。
引言
有时你有一些具有 1:1 关系的数据,你将它们放入 Hashtable
中使用一段时间后,意识到你需要从表中的值来查找键。本文介绍一个类来解决这个问题。
背景
最简单的解决方案是拥有两个哈希表(一个正向,一个反向),并将所有内容都添加到这两个表中。这有点麻烦;为什么不创建一个类来管理它,并避免我们重复输入呢?在遇到这个问题几次后,我决定不再重复输入任何东西。于是就有了 BidirHashtable
,一个双向 Hashtable
。
使用代码
BidirHashtable
很容易创建,尽管它不支持像 Hashtable
那样丰富的构造函数集。
BidirHashtable bh = new BidirHashtable();
BidirHashtable
的接口与 Hashtable
的接口基本相同,除了它在内部管理着两个 Hashtable
对象。 例如
bh[1] = 101;
bh[2] = 102;
注意:您需要确保只使用 1:1 关系。 虽然不可能用 Hashtable
或 BidirHashtable
建立 1:n 关系,但可以用 Hashtable
建立 n:1 关系。 然而,BidirHashtable
的设计并没有考虑到 n:1,因为对于 BidirHashtable
来说,这意味着反向表存在 1:n 关系——这显然是不可能的。 所以请注意——不要尝试这样做。
bh[1] = 101;
bh[2] = 101; // don't try this
检查元素是否在表中很容易
System.Diagnostics.Debug.Assert( bh.Contains(1) );
System.Diagnostics.Debug.Assert( bh.ContainsValue(101) );
注意 ContainsValue()
函数。 这在 Hashtable
中,但在 BidirHashtable
中,它实际上更快,因为它使用反向表进行查找。
正向查找也与 Hashtable
中一样
System.Diagnostics.Debug.Assert( (int) bh[1] == 101 );
但是,反向查找是新的
System.Diagnostics.Debug.Assert( (int) bh.ReverseLookup(101) == 1 );
为了易用性和效率,BidirHashtable
还支持一些转换和额外的构造方法。 例如
public BidirHashtable(IDictionary dict)
这个构造函数接受一个 Hashtable
或其他 IDictionary
,并从中初始化 BidirHashtable
。
内置了双向的显式强制转换。 请注意,它们会导致源对象被克隆为目标对象。 尽管如此,它们使得使用 BidirHashtable
更加容易
Hashtable ht = (Hashtable) bh;
BidirHashtable bh2 = (BidirHashtable) ht;
这个函数创建一个新的 BidirHashtable
,它被附加到输入的 Hashtable
。 使用时请小心,但它可以是一个有用的优化
public static BidirHashtable Attach(Hashtable ht)
如果出于任何原因,你想交换方向,只需交换内部的 Hashtable
对象即可。 这个函数完成了这个任务
public void ReverseDirection()
BidirHashtable
实现了 IDictionary
、ICollection
、IEnumerable
和 ICloneable
。 它(尚未)实现 ISerializable
,尽管最终可能会添加。
关注点
编写这个类是为数不多的情况之一,一旦它编译通过,它基本上就可以工作了。 我后来确实添加了一些东西,但它是一个简单的类。 您可以在我的网站上找到更多信息。
历史
- 2003-08-30 - 1.0 - 初始版本