IList与ArrayList简单实现与区别
ilist与arraylist简单实现与区别
第一个心得,是我看某本书提到,ilist用起来要比arraylist快
//测试list容器的功能
void main(void)
{
//list1对象初始为空
intlist list1;
//list2对象最初有10个值为6的元素
intlist list2(10,6);
//list3对象最初有3个值为6的元素
intlist list3(list2.begin(),--list2.end());
//声明一个名为i的双向迭代器
intlist::iterator i;
//从前向后显示各list对象的元素
put_list(list1,"list1");
put_list(list2,"list2");
put_list(list3,"list3");
//从list1序列后面添加两个元素
list1.push_back(2);
list1.push_back(4);
cout<<"list1.push_back(2) and list1.push_back(4):"<<endl;
put_list(list1,"list1");
//从list1序列前面添加两个元素
list1.push_front(5);
list1.push_front(7);
cout<<"list1.push_front(5) and list1.push_front(7):"<<endl;
put_list(list1,"list1");
//在list1序列中间插入数据
list1.insert(++list1.begin(),3,9);
cout<<"list1.insert(list1.begin()+1,3,9):"<<endl;
put_list(list1,"list1");
//测试引用类函数
cout<<"list1.front()="<<list1.front()<<endl;
cout<<"list1.back()="<<list1.back()<<endl;
//从list1序列的前后各移去一个元素
list1.pop_front();
list1.pop_back();
cout<<"list1.pop_front() and list1.pop_back():"<<endl;
put_list(list1,"list1");
//清除list1中的第2个元素
list1.erase(++list1.begin());
cout<<"list1.erase(++list1.begin()):"<<endl;
put_list(list1,"list1");
//对list2赋值并显示
list2.assign(8,1);
cout<<"list2.assign(8,1):"<<endl;
put_list(list2,"list2");
//显示序列的状态信息
cout<<"list1.max_size(): "<<list1.max_size()<<endl;
cout<<"list1.size(): "<<list1.size()<<endl;
cout<<"list1.empty(): "<<list1.empty()<<endl;
//list序列容器的运算
put_list(list1,"list1");
put_list(list3,"list3");
cout<<"list1>list3: "<<(list1>list3)<<endl;
cout<<"list1<list3: "<<(list1<list3)<<endl;
//对list1容器排序
list1.sort();
put_list(list1,"list1");
//结合处理
list1.splice(++list1.begin(), list3);
put_list(list1,"list1");
put_list(list3,"list3");
}
、如何使用arraylist
最简单的例子:
arraylist list = new arraylist();
for( int i=0;i<10;i++ ) //给数组增加10个int元素
list.add(i);
//..程序做一些处理
list.removeat(5);//将第6个元素移除
for( int i=0;i<3;i++ ) //再增加3个元素
list.add(i+20);
int32[] values = (int32[])list.toarray(typeof(int32));//返回arraylist包含的数组
这是一个简单的例子,虽然没有包含arraylist所有的方法,但是可以反映出arraylist最常用的用法。
3、arraylist重要的方法和属性
(1)构造器
arraylist提供了三个构造器:
public arraylist();
默认的构造器,将会以默认(16)的大小来初始化内部的数组
public arraylist(icollection);
用一个icollection对象来构造,并将该集合的元素添加到arraylist
public arraylist(int);
用指定的大小来初始化内部的数组
(2)issynchronized属性和arraylist.synchronized方法
issynchronized属性指示当前的arraylist实例是否支持线程同步,而arraylist.synchronized静态方法则会返回一个arraylist的线程同步的封装。
如果使用非线程同步的实例,那么在多线程访问的时候,需要自己手动调用lock来保持线程同步,例如:
arraylist list = new arraylist();
//...
lock( list.syncroot ) //当arraylist为非线程包装的时候,syncroot属性其实就是它自己,但是为了满足icollection的syncroot定义,这里还是使用syncroot来保持源代码的规范性
...{
list.add( “add a item” );
}
如果使用arraylist.synchronized方法返回的实例,那么就不用考虑线程同步的问题,这个实例本身就是线程安全的,实际上arraylist内部实现了一个保证线程同步的内部类,arraylist.synchronized返回的就是这个类的实例,它里面的每个属性都是用了lock关键字来保证线程同步。
****
但是,使用这个方法(arraylist.synchronized)并不能保证枚举的同步,例如,一个线程正在删除或添加集合项,而另一个线程同时进行枚举,这时枚举将会抛出异常。所以,在枚举的时候,你必须明确使用 syncroot 锁定这个集合。
hashtable与arraylist关于线程安全性的使用方法类似
list和arraylist的定义在注释中给出,可以看出来其实都差不多。arraylist只是多了icloneable,还少了几个泛型接口继承。
在后面代码中都用add方法向list中添加int类型数据,然后通过foreach形式枚举数据,注意!枚举部分的代码是有问题的,我们在(下)中会提到。
这里还要推荐一个非常棒的工具ilspy,是sharpdevelop开发的,强烈建议dotnet程序员都下载使用。
我把ilspy disassemble出来的c#代码和il代码分别列在后面。注意对于arraylist的foreach语句,c#形式的代码与源代码有些差别(79 到96行),编译器加入一个ienumerator enumerator2 = cfromarraylist.getenumerator();本地变量。
另外使用int num5 = (int)enumerator2.current;这样访问iterator。而且还加入了idisposable的finally部分。
再继续看il代码部分,对于list形式,il代码没有box装箱指令,而arraylist在145行有个box指令,这是性能差别之一。
但是奇怪的是,在枚举部分,ilspy生成的(以及ildasm)il代码,对于arraylist和list而言,基本上差别不大,一样也有对 movenext和current以及idisposable接口的调用。
只不过arraylist多出unbox和box的指令。
运行结果如我们所料,list要比arraylist快不少。
补充:asp.net教程,.Net开发