您的位置:首页 > 编程语言 > C#

C#中HashTable的用法 【转】

2013-06-19 13:33 906 查看
一,哈希表(Hashtable)简述

在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似keyvalue的键值对,其中key通常可用来快速查找,同时key是区分大小写value用于存储对应于key的值。Hashtable中keyvalue键值对均为object类型,所以Hashtable可以支持任何类型的keyvalue键值对.

二,哈希表的简单操作

在哈希表中添加一个keyvalue键值对:HashtableObject.Add(key,value);
在哈希表中去除某个keyvalue键值对:HashtableObject.Remove(key);
从哈希表中移除所有元素: HashtableObject.Clear();
判断哈希表是否包含特定键key: HashtableObject.Contains(key);
下面控制台程序将包含以上所有操作:
using System;
using System.Collections; //使用Hashtable时,必须引入这个命名空间
class hashtable
{
public static void Main()
{
Hashtable ht=new Hashtable(); //创建一个Hashtable实例
ht.Add("E","e");//添加keyvalue键值对
ht.Add("A","a");
ht.Add("C","c");
ht.Add("B","b");

string s=(string)ht["A"];
if(ht.Contains("E")) //判断哈希表是否包含特定键,其返回值为true或false
Console.WriteLine("the E key exist");
ht.Remove("C");//移除一个keyvalue键值对
Console.WriteLine(ht["A"]);//此处输出a
ht.Clear();//移除所有元素
Console.WriteLine(ht["A"]); //此处将不会有任何输出
}
}

三,遍历哈希表

遍历哈希表需要用到DictionaryEntry Object,代码如下:

//遍历Hashtable中的值并输出
foreach (DictionaryEntry each in Info)
{
Response.Write(each.Key.ToString() + " == " + each.Value.ToString() + "<br />");
}


四,对哈希表进行排序

对哈希表进行排序在这里的定义是对keyvalue键值对中的key按一定规则重新排列,但是实际上这个定义是不能实现的,因为我们无法直接在Hashtable进行对key进行重新排列,如果需要Hashtable提供某种规则的输出,可以采用一种变通的做法
ArrayList akeys=new ArrayList(ht.Keys); //别忘了导入System.Collections
akeys.Sort(); //按字母顺序进行排序
for(string skey in akeys)
{
Console.Write(skey + ":");
Console.WriteLine(ht[skey]);排序后输出
}

向哈希表中添加类并读取出类属性的方法:

public person()
{
//
//TODO: 在此处添加构造函数逻辑
//

}
public string Name;
public int Age;
public string sex;
public string MyInfo()
{
return "我的名字是:"+Name+"年龄:"+Age+"性别:"+sex;
}

hashTable.Add("person", new person() { Name = "hashTable", sex = "sex", Age = 12 });

foreach (var key in hashTable.Keys)
{
var r = hashTable[key];
person a =(person)r;
string aa = a.Age.ToString();
}

foreach (DictionaryEntry item in hashTable)
{
person p = (person)item.Value;
strHashTable += p.Name + "/" + p.Age + "/" + p.sex;
}

一、哈希表(Hashtable)简述

在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似key/value的键值对,其中key通常可用来快速查找,同时key是区分大小写;value用于存储对应于key的值。Hashtable中key/value键值对均为object类型,所以Hashtable可以支持任何类型的key/value键值对。

二、哈希表的简单操作

在哈希表中添加一个key/value键值对:HashtableObject.Add(key,value);
在哈希表中去除某个key/value键值对:HashtableObject.Remove(key);
从哈希表中移除所有元素: HashtableObject.Clear();
判断哈希表是否包含特定键key: HashtableObject.Contains(key);
下面Windows程序将包含以上所有操作:

[csharp] view plaincopyprint?

private void button1_Click(object sender, System.EventArgs e)

{

Hashtable ht=new Hashtable(); //创建一个Hashtable实例

ht.Add("E","e");//添加key/value键值对

ht.Add("A","a");

ht.Add("C","c");

ht.Add("B","b");

MessageBox.Show("键A的值是: " + (string)ht["A"]);

MessageBox.Show("是否存在键E:" + ht.Contains("E").ToString()); //判断哈希表是否包含特定键,其返回值为true或false

ht.Remove("C");//移除一个key/value键值对

MessageBox.Show("已经移除C键:" + ht["C"]);

ht.Clear();//移除所有元素

MessageBox.Show("已经移除所有元素" + ht["A"]); //此处将不会有任何输出

}

private void button1_Click(object sender, System.EventArgs e)
{
Hashtable ht=new Hashtable(); //创建一个Hashtable实例

ht.Add("E","e");//添加key/value键值对
ht.Add("A","a");
ht.Add("C","c");
ht.Add("B","b");

MessageBox.Show("键A的值是: " + (string)ht["A"]);
MessageBox.Show("是否存在键E:" + ht.Contains("E").ToString()); //判断哈希表是否包含特定键,其返回值为true或false

ht.Remove("C");//移除一个key/value键值对
MessageBox.Show("已经移除C键:" + ht["C"]);

ht.Clear();//移除所有元素
MessageBox.Show("已经移除所有元素" + ht["A"]); //此处将不会有任何输出
}


三、遍历哈希表

遍历哈希表需要用到DictionaryEntry Object,代码如下:

[csharp] view plaincopyprint?

foreach(DictionaryEntry de in ht) //ht为一个Hashtable实例

{

MessageBox.Show(de.Key.ToString());//de.Key对应于key/value键值对key

MessageBox.Show(de.Value.ToString());//de.Key对应于key/value键值对value

}

foreach(DictionaryEntry de in ht) //ht为一个Hashtable实例
{
MessageBox.Show(de.Key.ToString());//de.Key对应于key/value键值对key
MessageBox.Show(de.Value.ToString());//de.Key对应于key/value键值对value
}


四、对哈希表进行排序

对哈希表进行排序在这里的定义是对key/value键值对中的key按一定规则重新排列,但是实际上这个定义是不能实现的,因为我们无法直接在Hashtable进行对key进行重新排列,如果需要Hashtable提供某种规则的输出,可以采用一种变通的做法:

[csharp] view plaincopyprint?

ArrayList akeys=new ArrayList(ht.Keys); //别忘了导入System.Collections

akeys.Sort(); //按字母顺序进行排序

foreach(string skey in akeys)

{

MessageBox.Show(skey + ":");

MessageBox.Show(ht[skey].ToString());//排序后输出

}

ArrayList akeys=new ArrayList(ht.Keys); //别忘了导入System.Collections
akeys.Sort(); //按字母顺序进行排序
foreach(string skey in akeys)
{
MessageBox.Show(skey + ":");
MessageBox.Show(ht[skey].ToString());//排序后输出
}


[csharp] view plaincopyprint?

public void InitData()

{

string sql = @"select * from orders";

SqlConnection con = new SqlConnection("server=.;uid=sa;pwd=sa;database=NorthWind");

SqlDataAdapter sda = new SqlDataAdapter(sql, con);

DataTable dt = new DataTable();

sda.Fill(dt);

Hashtable htt = new Hashtable(5);

foreach (DataRow dr in dt.Rows)

{

htt.Add(dr["orderID"], dr["CustomerID"]);

}

ArrayList al = new ArrayList(htt.Keys);

al.Sort();

foreach (DictionaryEntry de in htt)

{

if (de.Value.ToString == "ALFKI")

{

Response.Write(de.Key + "Next .");

}

}

GridView1.DataSource = dt;

GridView1.DataBind();

}

参考:

哪个高手给你说“哈西表就是键(key)与值(value)的对应。”的?要么就是他不耐烦随便搪塞你的,要么就是他不是高手没有理解真正的含义。
“哈西表就是键(key)与值(value)的对应。”这句话实际上说的Dictionary——字典。当然哈希表本身也是一个字典,也就是说他是一个通过“键”查询“内容”的集合对象,只是他提供了一种字典本身没有规定的特性——高速。下面是关于HashTable的平均时间复杂度表(和其他数据结构比较,均不包括内存分配):

哈希表 链表 数组 排序数组
添加 O(c) O(1) O(1) O(log2(n))
查询 O(c) O(n/2) O(n/2) O(log2(n))
删除 O(c) O(1) O(1) O(n/2)

c是一个常数级别的东西,和n关系不是非常大,基本上相当于1~15之间,一般你可以认为是2或者3。这里面的数据不是很精准,大概意思意思。你可以看出来,哈希标有着各项性能均比较出色的表现,没有哪一向是排在最后面的,甚至和最快的都不会相差多少。但是随便哪一种数据结构都会至少有某一项是远远落后于哈希表的,所以在编译器里面就是用哈希表储存你定义的表识符的。
从上表也可以看出,哈希表最出色的地方在于查询。也就是说如果你需要在大量数据当中反反复复进行大量的(排序无关的)查询的话,用哈希表就最适合不过了。如果不是这种情况,用哈希表也不会表现太差。但是哈希表也有他的缺点:

1、他是一个字典,也就是说他需要你的数据中能有一个唯一的“键”来表识你的数据。比如说如果你的数据是某个人的姓名以及他的一些其他情况,那么一旦有同名的那就会出问题了——会被认为是同一个人,甚至你根本就没有办法把另外一个人添加进去。因此,没有或者不能保证有唯一键值的数据不能够用哈希表。实际上哈希表还需要这个“键”能够产生哈希值,只是在.NET里面任何东西都有哈希值(Object.Hashcode),所以你就不用担心这个问题了。

2、他是一个字典,也就是说他除了需要保存你的数据之外,还要保存你的“键”,或者还有一些且他的原因,使得它的空间额外开销是O(xN)级别的,也就是说会相对消耗更多的空间。如果数据量非常大的话,用哈希也会更容易受到限制。其他一些例如联表、树等在这方面要表现得好的多,他们最多也就需要O(4N)或者稍微多一点,哈希表的那个x要比这个大一些。表现得最好的是数组类的数据结构,根本就是0(这里讨论的是额外的)。实际上传统的哈希表是一次分配固定大小的空间,并且不会再变化的,因此很多时候会有很多空间是没有被利有到的,也就是说他的利用率比较低(这样有助于减小前面的c值),所以占用空间会非常大。不过.NET里面的哈希表默认的装载因子是1,也就是全满的,所以相对较好。当然,一般来说这些额外的空间都不会异常的大,一般都是可以接受的。这一点说明哈希表对于数据量太大或者对空间有严格要求的地方是不适合的,虽然你还是可以选择他。

3、哈希表之所以快,是因为它的每个元素在哈希表里面的存储位置是通过你的键的哈希值计算得到的,因此存储的顺序是随机的并且是不能够控制的。因此如果你需要排序,或者需要有排序相关的查询功能,例如找出身高为160到175之间的所有人,那么哈西表的表现就会非常差,尤其是这些值并不是键值的时候。这个时候排序数组,B树等能够提供比他优秀得多的性能。如果你的数据需要排序,或者排序相关的功能,那么就请你忘了哈希吧,它本身不但没有这个功能,甚至是和这个功能想冲突的。当然,你可以通过其他数据结构提供排序能力,但是这样会增加更多的额外空间开销,编码也会相对复杂不少。

简单点说,哈希表是:一个集合,一个字典,一个空间换时间的方法,一个随机乱序存储的对象
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: