public class Hashtable : IDictionary, ICollection,
IEnumerable, ISerializable, IDeserializationCallback, ICloneable
也就是说它继承有IDictionary,其实本身就是在Dictionary上实现的,与dictionary的使用没有多大的区别,相信这些接口你都能明白是咋回事的!
其实一直以前在计算机的术语上都是比较乱的,尤其是翻译过来的文章,更是千奇百怪。单就对英文来说,哈希表有人翻译成hashtable,有人翻译成hashmap,于上有些技术资料上为了把hashtable与hashmap分开,一个翻译成“哈希表”,一个翻译成"哈希桶“,其实这是翻译的人不懂计算机而导致的错误。不管是hashtable,还是hashmap指的都是哈希表,在VS中还真存在hashmap,只不过是承接了java.util.*中的hashmap,我们可以理解成哈希表的两个不同称呼就可以了!不管是hashtable还是hashmap都是哈希表。
事实上,还真存在哈希桶的概念。我先说一下哈希表的来源。
当初hash指的就是一个线性存在结构,也就是我们翻译过来的散列表,严格来说,散列表指的就是hash,而这时由于翻译过来的是散列表的原因,把这个称为哈希表。但事实上它却是一个线性结构,而非键值对。其实这就是是桶的来源,后来由于哈希表的翻译问题,所以才将线性结构称为桶,而非表,用以加以区分。
而键值对,严格来说它十分象一种央射关系,所以对于键值对构成的结构,有人称其为hashmap,而有人说这不就是一个二维结构么,于是有人称其为hashtable,其实一般情况下,如果二维表只有二列时,称其为map还是比较合适的,而若是三列或以上,你当然塌辩此不能称其为map,只能称其为table了。也就是说hashtable说明了键值对的二维结构,而hashmap则更精确地出这个二维结构是由两列构造的。其实对于我们使用的hashtable来说,它们指的是同一样的东西,但不管是hashtable还是hashmap在汉语中没有区别的,都是哈希表,而在英文中两者还是有轻微的差别。
那么如果他只是一个线性结构而不是键值对呢?由于我们对于散列表(hash)或称哈希表已经使用过这个概念,我们将如何区分呢?这时又一个概念有助于我们的理解,就是哈希桶,我也不知道这个概念到底怎么来的,但我一听到这样桶的概念,我就是知道它存储的不同的键值对,而是线性结构,也就和我们的散列表(hash)对应起来了!也就是说,它才是我们真正的散列。
在C#中存在这样的一个结构的,那就是hashset<T>,还实现了泛型接口!这个是对应了散列表(hash)的,有人称其为哈希桶,真的很合适的!
dictionary与hashset同时都在system.collections.generic空间中。
但是,对于哈希表的定义你必须要了解的,hash就是将关键码存储在hash结构中,这里有一个词叫关键码,有些书上倒是直接说了,将不同的关键码存存储在hash结构中,也就是说大家都没有注意的到是关键码,一旦说关键码,其实就是说两者不可重复。也就是说不管是hashtable还是hashmap其关键码都是不允许重复的。所以不存在键重复一说,如果真能重复了,那就不叫键了!但对于值是没有要求的,只要求键是不会重复的。
所以没有重复这一说,我给用散列表举列说明一下吧:
假定是两个重复数字5,我在排列第一个时,排在了5号位,而排第二个时,由于冲突的原因,我排在了6号位。那么,我现在用5去查找,结果永远只查到5号位,不可能查到6号位。
而对于hash表也是一样的,一个是alice为键,它对应的两个值,一个是1,一个是3,alice本来应团迅该放在5号位,第一个alice,1被放在了5号位,第二个alice,3由于重复被放到了6号位,根据查找,我只能找到5号位的alice=1(找到了就停止),永远不可能找到6号位的灶毁alice=3,那么,这个alice=3还有存在的意义么?
所以不管是哈希表还是哈希桶,其关键码都是不重复的,重复的都不能再叫关键码了!
如果真想重复,那么我们不可能再使用hashtable,必须另外键立一个结构,hashtable的目的就是快速查找,显然重复的情况下不能在hashtable上快速查找了,那么你就可以考虑使用array,list,arraylist等结构,或在相应的结构上进行扩展。
////////////////////////////////////////////////////////////////
顺便说一下,dictionary也是不允许重复的!
在开发Web项目的时候,会有一个配置文件Web.config,用来存放一些全局的变量,如连接数据库用的字符串。相应的,在开发winform程序时,也念或有一个配置文件,它就是App.config,这个文件的作用与
Web.config大致相同,也可以用来存放程序所用的全局变量及Value值。
来看一个app.config文件的例子:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<!--图片存放路径-->
<add key="ImgPath" value="D:\img\" />
</appSettings>
</configuration>
可以看出,app.config和web.config一样,嗯,它也是一个XML文件。那怎么对这个文件中的元素进行读取 *** 作呢?很简单,来看代码:
string strPath = System.Configuration.ConfigurationSettings.AppSettings["ImgPath"].ToString()
这样就可以把app.config文件中ImgPath这个元素的Value值读取出来了。那怎么改写元素的值呢?如果你认为像读那样的去写,像这样的代码:
System.Configuration.ConfigurationSettings.AppSettings["磨链ImgPath"] = @"E:\img\"//这样写是没用的
在对app.config文件的元素Value值进行修改 *** 作时,只能把app.config文件当作一个普通的XML文件来对待,仔游伍利用
System.Xml.XmlDocument类把这个app.config文件读到内存中,并通过System.Xml.XmlNode类找到
appSettings节点,通过System.Xml.XmlElement类找到节点下的某个元素,利用SetAttribute方法来修改这个元素
的值后,最后再将app.config文件保存到原的目录中,这样,才算完成了对一个元素Value值的修改 *** 作。下面这个方法可完成对
app.config文件appSettings节点下任意一个元素进行修改,当然,你也可能修改这个方法,达到修改任意节点,任意元素的Value值。
public static void SetValue(string AppKey, string AppValue)
{
System.Xml.XmlDocument xDoc = new System.Xml.XmlDocument()
xDoc.Load(System.Windows.Forms.Application.ExecutablePath + ".config")
System.Xml.XmlNode xNode
System.Xml.XmlElement xElem1
System.Xml.XmlElement xElem2
xNode = xDoc.SelectSingleNode("//appSettings")
xElem1 = (System.Xml.XmlElement)xNode.SelectSingleNode("//add[@key='" + AppKey + "']")
if (xElem1 != null) xElem1.SetAttribute("value", AppValue)
else
{
xElem2 = xDoc.CreateElement("add")
xElem2.SetAttribute("key", AppKey)
xElem2.SetAttribute("value", AppValue)
xNode.AppendChild(xElem2)
}
xDoc.Save(System.Windows.Forms.Application.ExecutablePath + ".config")
}
注意这个方法中if条件else下的语句,当在文件中没有找到给定的元素时,方法会创建这个元素。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)