C#中HashTable的用法

http://www.cnblogs.com/liuwenjun830/archive/2006/07/28/462182.html

一,哈希表(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; file使用Hashtable时,必须引入这个命名空间
class hashtable
{
  public static void Main()
  {
  Hashtable ht=new Hashtable(); file创建一个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)) file判断哈希表是否包含特定键,其返回值为true或false
    Console.WriteLine(the E keyexist);
  ht.Remove(C);移除一个keyvalue键值对
  Console.WriteLine(ht[A]);此处输出a
  ht.Clear();移除所有元素
  Console.WriteLine(ht[A]); file此处将不会有任何输出
  }
}

三,遍历哈希表

 遍历哈希表需要用到DictionaryEntry Object,代码如下:
 foreach(DictionaryEntry de in ht) fileht为一个Hashtable实例
 {
   Console.WriteLine(de.Key);de.Key对应于keyvalue键值对key
   Console.WriteLine(de.Value);de.Key对应于keyvalue键值对value
 }

四,对哈希表进行排序

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

c#学习笔记--Hashtable初探

08-10

在学习Hashtable时,看到书上有一些话不太明白。rn如rn(1)如果定义自己健的GetHashCode(),就必须和健的Equals()保持一致,即如果KeyA.Equals(KeyB)为true,rn那么,KeyA.GetHashCode()的值必须和KeyB.GetHashCode()的值相等。rn(2)在Hashtable内部用KeyA.Equals(KeyB)来判定两个健是否指向同一个引用。rn(3)如果在Hashtable中,两个条目有相同的列散值,Hashtable就必须寻找最近的可利用的自由单元来存储rn第二个条目rn经过思考,对以上疑问有一些自己的想法。写出来请大家来探讨。rn有如下程序:rnHashtable HashT = new Hashtable(7);rnClassKey KeyA = new ClassKey(); //ClassKey 为已经定义了的健rnClassKey KeyB = KeyA; //KeyA,KeyB指向相同的引用rnClassData DataA = new ClassData(); //ClassData为已经定义了的Hashtable元素rnClassData DataB = new ClassDate();rnHashT.Add(KeyA,DataA);rnHashT.Add(KeyB,DataB);rn在程序执行到HashT.Add(KeyA,DataA)时,在内存中的结构如下所示:rnrn内存区 Hashtable 内存区rn 健 元素rn______ ____ _____ _________rnrnClassKey<------KeyA--->DataA------>ClassDatarn(实例) (引用) (引用) (实例)rnrn此时,在Hashtable中存储指向类ClassKey实例的引用keyA和指向类ClassData实例的引用DataA,rn并且KeyA.GetHashCode()得到的值是DataA的内存地址.然后,程序继续往下执行,rn在程序执行到HashT.Add(KeyB,DataB)时,在内存中的结构如下所示:rnrnrn//rnrnrnrnrn   在计算KeyB.GetHashCode()的值时,因为KeyA和KeyB指向同一个对象,既KeyA.Equals(KeyB)返回rntrue,所以KeyA.GetHashCode()的值必须等于KeyB.GetHashCode()的值才符合逻辑(因为KeyA,KeyBrn指向同一个对象).这样KeyB.GetHashCode()的结果就也指向DataA的内存地址。这样就会覆盖DataA。rn(可以通过不允许在hashtable中添加指向相同对象的引用来解决,但在Hashtable内只要两个健有不rn同外观表现就是合乎逻辑的,因此这样限制会引起逻辑混乱).这样一来就有了现在的这种解决方法,rn既如果在Hashtable中,两个条目有相同的列散值,Hashtable就必须寻找最近的可利用的自由单元来存储rn第二个条目。这也同时说明了,如果KeyA.Equals(KeyB)为true,那么KeyA.GetHashCode()和KeyB.GetHashCode()rn值就必须相同才能用正确的结果。rn  而编写一个好的散列算法并不简单,有很苛刻的条件我们的Hashtable才能工作的令人满意。但microsoftrn已经为我们编写好了String类的散列算法,能保证计算出来的列散值平均分布在整个int的空间内。我们rn可以利用这个来编写我们自己的列散算法。举例如下:rnclass ClassKeyrnrn //类的字段rn private String str;rn private int i;rn //重载object的Equals()方法rn public override bool Equals(object obj)rn rn ClassKey otherKey=obj as otherKeyrn if(localKey==null)rn return false;rn if(this.str==otherKey.str || this.i=otherKey.i)rn return true;rn return false;rn rn //重载object的ToString()方法rn public override String ToString()rn rn return str+i.ToString();rnrn rn //重载object的GetHashCode()方法rn public override String GetHashCode()rn rn return ToString().GetHashCode();rnrn rnrn在这个类中我们坚持这样的原则来利用microsoft为我们便写好的String类的GetHashCode()rn方法,并且保证了Hashtable的工作原理--Hashtable确定两个健KeyA,KeyB是否相等的方式是调用rnKeyA.Equals(KeyB),如果KeyA.Equals(KeyB)为true,则KeyA.GetHashCode()和KeyB.GetHashCode()rn必须返回相同的散列值.rn (1)当KeyA.Equals(KeyB)为true时,KeyA.ToString()和KeyB.ToString()应该有相同的值rn (2)在GetHashCode()方法中调用类的ToSting()方法返回一个String类的对象,并调用这个rnString类对象的GetHashCode()方法,即ToString().GetHashcode(),这样我们就充分利用了microsoftrn的String类的GetHashCode()来为我们工作。他的正确性可有推力来保证。rn  既。如果Keya.Equals(KeyB)为true,那么根据第一条,KeyA.ToString()和KeyB.ToString()应该rn有相同的值,而在我们的GetHashCode()中调用了ToString().GetHashCode(),所以,就会返回相同的列散rn值(这个结果由microsoft来保证,因为我们调用了他编写的GetHashCode()函数,所以,如果出错,不是我的问题)。rnrnrnrn 论坛

c# hashtable排序问题

02-02

以下是我编的程序,主要功能,是可以输入一句话,然后统计这段话中每个单词出现的次数,然后出现次数少的在前,多的在后,就是说按升序排列,应该是对HashTable的VALUE排序,不过我弄不出来,以下是我的代码!我是用VS 2005进行编辑的!rnusing System;rnusing System.Collections;rnnamespace ConsoleApplication1rnrn /// rn /// Summary description for Class1.rn /// rn class Class1rn rn /// rn /// The main entry point for the application.rn /// rn [STAThread]rn static void Main(string[] args)rn rn Console.WriteLine("Please enter one sentence");rn String strSentence = Console.ReadLine();rn String[] strArr = strSentence.Split();rnrn Hashtable hTable = new Hashtable();rn for (int i = 0; i < strArr.Length; i++)rn rn String strCurrWord = strArr[i];rn if (hTable.ContainsKey(strCurrWord))rn rn int counter = (int)hTable[strCurrWord];rn counter++;rn hTable[strCurrWord] = counter;rn rn elsern rn hTable[strCurrWord] = 1;rn rnrn rnrn ArrayList newArrayList = new ArrayList(hTable.Values);rnrn newArrayList.Sort(); // 升序排列rnrn ArrayList newArray = new ArrayList();rnrn foreach (int score in newArrayList)rn rnrn if (!newArray.Contains(score))rn rn ICollection colKeys = hTable.Keys;rn IEnumerator it = colKeys.GetEnumerator();rnrn while (it.MoveNext())rn rn if ((int)it.Current== score)rn rnrn String strKey = (String)it.Current;rn Console.Out.WriteLine("The word" + strKey + "has appeared" + hTable[strKey] + "times!");rn rnrn rnrn newArray.Add(score);rnrn rn rnrn Console.ReadLine();rn rn rnrnrn 论坛

没有更多推荐了,返回首页