因为最近经常用到list,所以对它可以动态调节长度很感兴趣,决定一探究竟,结果还真发现了一些有意思的东西;
大家看下面的代码:
List<int> list = new List<int>();
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
list.Add(1);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
list.Add(2);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
list.Add(3);
list.Add(4);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
list.Add(5);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
list.Add(6);
list.Add(7);
list.Add(8);
list.Add(9);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
他的执行结果是:

我们发现当你没有元素的时候它的list长度为0;
添加第一个元素之后它的长度变成了4个;当添加第五个元素的时候它的表长达到了八个,在添加到第九个元素的时候它的list表长变成了16.
由此我们可以推断,他并不是真正意义上的可自由添加删除数据,list表也有自己的长度,
经过翻阅一些资料,以及看了c#的源代码,发现:
list在新建表之后的初始长度为0,添加第一个元素之后会生成一个长度为四的表,也就是初始长度
每此添加数据的时候会判断是否超出表长,如果超出表长那么就新建一个list表(这个表的长度是原来表的二倍),
然后list表会把之前的表数据复制到新表中
但是之前的表去了哪里呢,在这里我推测,他复制表之后,他直接把指针指向了新的表,并没有管当前的表,所以当前的表会变成内存垃圾等着cg回收
那么我们怎么优化list来提高效率呢,其实我们可以自定义表的长度,
像这个样子:
//定义list长度
List<int> list = new List<int>(1);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
list.Add(1);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
list.Add(2);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
list.Add(3);
list.Add(4);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
list.Add(5);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
list.Add(6);
list.Add(7);
list.Add(8);
list.Add(9);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
list.Remove(9);
list.Remove(8);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);

他的结果是这个样子,也从侧面的反映了我们的结论。
那么为什么我推荐我们建立list表的时候自定义表的大小呢,
因为我们自定义list表的大小之后可以防止两个事情发生:
1.频繁的添加数据造成的内存垃圾。
2.由于表过于巨大,再次超出表的上限时会出现巨大的内存占用。而且里面还是空数据,根本用不上。
题外话:我们今天讨论的是c#的list,为什么这么说呢
因为在查阅资料的时候,我发现c#的list和java的list完全不是一个东西,对于java来说list是一个接口,他的初始长度是10,每次增长长度是之前的1.5倍。
而c#的list和arraylist实现的都是ilist接口,初始长度和每次超级加倍的倍数也不一样。、

2310

被折叠的 条评论
为什么被折叠?



