在C#的容器中,常用的三个容器数组,ArrayList,Hashtable..数组比较简单,实现某种单一数据的存储,但是并不能自由插入,移除和容纳不同的对象..,所以ArrayList是数组的替代品,并且由于ArrayList可以自由的添加,删除,插入,读取,给我们提供了足够大的自由性,颇得我的青睐..不过使用中,难免有些缺点,感觉最麻烦的就是检测某对象是否在Items中..因为每一个new出来的Class在内存中的表现不相同,即便是同一个类,你new出来两个,然后再判断,也是会一样的!!所以每次使用ArrayList.Contains()检测对象的时候,难免都得不到自己想要的结果..因为每个Class都是继承自Object类..而ArrayList.Contains()的实现是IList.Contains,而此方法是调用Class中的Equals方法判断是否相等,这个时候,可以在自己的对象中覆写Object.Equals方法,以达到自己的目的..注意,如果你覆写了Equals方法,则也要覆写GetHashCode(),因为Equals是用获取Object.GetHashCode()来做判断的.看看下面的代码就明白:

 1检测Class是否相等using System;
 2检测Class是否相等
 3检测Class是否相等namespace HashCode_Test
 4}

这里是测试代码:

 1检测Class是否相等System.Collections.ArrayList arr = new System.Collections.ArrayList();
 2检测Class是否相等
 3检测Class是否相等int i = 0;
 4


相信上面的代码很容易看的懂..在我的Class2类中覆写了GetHashCode() ,ToString() ,Equals(object o),并重载了==运算符和!=运算符..将传递的id作为HashCode,然后判断当前传递的对象Object.GetHashCode是否等于当前对象的GetHashCode..这样就解决了ArrayList.Contains不能对Class做出正确判断的问题..

另外,还有一个容器Hashtable的使用和判断,并不能用上面的方法解决..因为Hashtable.Contains的实现方法是IDictionary.Contains来做判断..需要实现IDictionary接口的方法才可以.因为牵涉到的内容比较多.所以不能在这里全部写完..关于具体的方法和实现,我会找时间写出来的..

最后大家可以自己做一个没有实现Equals方法的类,再用ArrayList.Contains来做判断..可以看到结果都是flase..和上面的代码是个对比..
这个方法不仅可以用在ArrayList,而且也可以在多个地方使用,比如两个Class之间的关联?Class1和Class2是否关联??
既然需要再次重写Equals方法,今天就用Hashtable的实现,先说一下Hashtable,首先Hashtable保存的是以(键/值)为一对插入的..你可以方便的通过键来查找值,在国外的书中称为字典,他的作用也如其名一样..使用起来很类似字典..你知道一个字母a ,要查找对应字母a的值,可以这么写Hashtable["a"],这样就查到了对应a的值..但是需要注意一点,就是添加到Hashtable不能重复,必须有唯一性.并且因为Hashtable添加/删除是无序的,所以速度要快..就是因为它们是无序的,所以你不能通过索引,类似string[0].string[1]这样的方式访问到Hashtable中的数据.针对这样的情况,适应于下列地方,你知道key,但是value不确定,并且需要频繁的插入和删除操作,而这个时候数组和ArrayList就不是最佳的选择,因为在你获取某对象的时候,需要遍历..而Hashtable则比他们的效率要高..

下面是个简单的例子对ArrayList和Hashtable做了个对比:
 1检测Class是否相等int i;
 2检测Class是否相等System.Collections.Hashtable hs = new System.Collections.Hashtable();
 3检测Class是否相等System.Collections.ArrayList arr = new System.Collections.ArrayList();
 4检测Class是否相等
 5检测Class是否相等long StartTime  = DateTime.Now.Ticks;
 6StartTime) );

上面的代码执行结果:
1检测Class是否相等ArryList添加执行时间:0
2检测Class是否相等Hashtable添加执行时间:300432
3检测Class是否相等ArryList查找执行时间:10214688
4检测Class是否相等Hashtable查找执行时间:0
5检测Class是否相等ArryList查找执行时间:701008
6检测Class是否相等Hashtable查找执行时间:0

结果可以说明,使用正确的容器对程序的优化是至关重要的..而选择正确的容器,也完全在于对容器的了解和对业务的熟悉..这里需要注意一点,开头的地方说添加也很快,但是Hashtable的添加要比ArrayList慢很多..主要是因为Hashtable要对key做一系列的索引算法,也是为了更好的查找和删除做的准备工作... 另外这里提示一点,就是在Hashtable初始化的时候可以给它指定默认容量和加载因子,其中加载因子越小,则平均查找速度就越快,但内存消耗就越大..默认的容量是16,加载因子是1..加载因子的取值范围是0.1-1之间..可以根据你的数据大小适当的调整容量和加载因子来提高速度..

 1检测Class是否相等System.Collections.Hashtable hs = new System.Collections.Hashtable();
 2检测Class是否相等int i;
 3检测Class是否相等long StartTime  = DateTime.Now.Ticks;
 4检测Class是否相等for ( i = 0; i < 10000;i ++ ) 
 5StartTime) );

上面的代码执行结果:
1检测Class是否相等hs添加执行时间:200288
2检测Class是否相等hs2添加执行时间:100188
这个结果,经过我测试,在你i<40000的时候,是明显的,但是i>40000的时候,效率就很差了.甚至是不如默认的...并且根据数据的不同,这个结果都会有偏差,不过数据量保持在某个值(这个值也是很变化的)以下的时候,调整加载因子比默认的速度还是要快点的...


如果你传递给Hashtable的key是Class,而如何保证key的唯一呢??因为Hashtable还是用到了HashCode做为验证唯一性,所以你还要在你的类覆写GetHashCode(),并且也要重写Equals()以判断是否相等..具体问题可以看  1检测Class是否相等//=============  用户类   ==================
 2检测Class是否相等public class User
 3}

相关文章: