65.9K
CodeProject 正在变化。 阅读更多。
Home

双向哈希表

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.70/5 (7投票s)

2003年9月1日

2分钟阅读

viewsIcon

76279

downloadIcon

794

演示了一个易于使用的双向哈希表,以方便反向查找。

引言

有时你有一些具有 1:1 关系的数据,你将它们放入 Hashtable 中使用一段时间后,意识到你需要从表中的值来查找键。本文介绍一个类来解决这个问题。

背景

最简单的解决方案是拥有两个哈希表(一个正向,一个反向),并将所有内容都添加到这两个表中。这有点麻烦;为什么不创建一个类来管理它,并避免我们重复输入呢?在遇到这个问题几次后,我决定不再重复输入任何东西。于是就有了 BidirHashtable,一个双向 Hashtable

使用代码

BidirHashtable 很容易创建,尽管它不支持像 Hashtable 那样丰富的构造函数集。

BidirHashtable bh = new BidirHashtable();

BidirHashtable 的接口与 Hashtable 的接口基本相同,除了它在内部管理着两个 Hashtable 对象。 例如

bh[1] = 101;
bh[2] = 102;

注意:您需要确保只使用 1:1 关系。 虽然不可能用 HashtableBidirHashtable 建立 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 实现了 IDictionaryICollectionIEnumerableICloneable。 它(尚未)实现 ISerializable,尽管最终可能会添加。

关注点

编写这个类是为数不多的情况之一,一旦它编译通过,它基本上就可以工作了。 我后来确实添加了一些东西,但它是一个简单的类。 您可以在我的网站上找到更多信息。

历史

  • 2003-08-30 - 1.0 - 初始版本
© . All rights reserved.