C#中List<T>存放元素的工作机制
作者:Darren?Ji 时间:2022-09-29 16:31:23
List<T>是怎么存放元素?我们扒一段List<T>的一段源码来一窥究竟。
using System;
using System.Diagnostic;
using System.Collections.ObjectModel;
using System.Security.Permissions;
namespace System.Collections.Generic
{
...
[Serializable()]
public class List<t> : IList<t>, System.Collections.IList
{
private const int _defaultCapacity = 4;
private T[] _items; //List<T>内部是依靠数组_items存放数据的
private int _size; //数组的长度
private int _version;
[NoSerialized]
private Object _syncRoot;
static T[] _emptyArray = new T[0];
//无参数构造函数 把_items设置成一个空的数组
public List()
{
_items = _emptyArray;
}
//此构造函数 给_items数组一个初始容量
public List(int capacity)
{
...
items = new T[capaicty];
}
//此构造函数 把集合类型参数拷贝给_items数组
public List(IEnumerable<t> collection)
{
...
ICollection<t> c = collection as ICollection<t>;
if(c != null)
{
int count = c.Count; //把构造函数集合类型参数的长度赋值给临时变量count
_items = new T[count]; //List<T>内部维护的_items数组的长度和构造函数集合类型参数的长度一致
c.CopyTo(_items, 0); //把构造函数集合的所有元素拷贝到_items数组中去
_size = count; //_items数组的长度就是构造函数集合类型参数的长度
}
else
{
_size = 0;
_items = new T[_defaultCapacity];
...
}
}
//通过设置这个属性,改变List<t>内部维护的_items数组的长度
public int Capacity
{
get {return _items.Length; }
set {
if(value != _items.Length){ //如果当前赋值和List<t>维护的内部数组_items长度不一致
if(value < _size){
//TODO: 处理异常
}
if(value > 0){
T[] newItems = new T[value]; //创建一个临时的、新的数组,长度为新的赋值
if(_size > 0){
//把临时的、新的数组拷贝给List<t>内部维护的数组_items,注意,这时_items的长度为新的赋值
Array.Copy(_items, 0, newItems, 0, _size);
}
} else {
_items = _emptyArray;
}
}
}
}
public void Add(T item)
{
if(_size == _items.Length) EnsureCapacity(_size + 1);
_items[_size++] = item;
...
}
//确保List<t>内部维护的_items数组的长度至少是给定的值
//如果_items数组原先的长度比给定的值小,就让_items数组的长度设置为原先的长度的2倍
privat void EnsureCapacity(int min)
{
if(_items.Length < min){
int newCapacity = _items.Length == 0 ? _defaultCapacity : _items.Legnth * 2;
if(newCapacity < min) newCapacity = min;
Capacity = newCapacity;
}
}
}
}
由此可见,向List<T>中存放元素的大致过程是这样的:
List<T>内部维护着一个数组_items,用来存放T类型的元素。
当有新的T类型元素存放进来,即调用Add(T item)方法。
Add(T item)方法内部调用EnsureCapacity(int min)方法确保List<T>的Capaicty属性值至少在原先长度上加1,最多是原先长度的2倍。
在给Capacity赋值的过程中,对_items的长度进行了扩容。
扩容后,再把新的T类型元素存放进来。
简单地说:
当有新的元素存放到List<T>中时,List<T>先对其维护的内部数组进行扩容,然后再把新元素放进来。
来源:https://www.cnblogs.com/darrenji/p/3843749.html
标签:C#,List,存放,元素
0
投稿
猜你喜欢
c#调用存储过程实现登录界面详解
2023-01-02 22:03:07
Spring集成MyBatis 及Aop分页的实现代码
2022-01-06 14:30:47
SpringCloud eureka(server)微服务集群搭建过程
2023-05-22 15:08:55
Android实现购物车及其他功能的角标
2021-12-24 10:54:54
java时间戳转日期格式的实现代码
2023-08-07 21:44:31
5种Android数据存储方式汇总
2023-08-06 06:49:04
android系统在静音模式下关闭camera拍照声音的方法
2021-09-04 00:34:20
java单例模式学习示例
2022-03-29 19:03:41
Android编程实现仿QQ发表说说,上传照片及弹出框效果【附demo源码下载】
2022-10-02 11:59:43
HttpServletResponse乱码问题_动力节点Java学院整理
2021-10-18 17:48:51
Android 利用反射+try catch实现sdk按需引入依赖库的方法
2022-09-19 22:09:08
C#自定义处理xml数据类实例
2022-07-02 11:00:39
完美解决关于禁止ViewPager预加载的相关问题
2021-07-05 11:50:50
Android HttpClient GET或者POST请求基本使用方法
2021-11-18 04:26:57
Java求两集合中元素交集的四种方法对比分析
2023-08-23 09:24:56
Springcloud Nacos基本操作代码实例
2023-07-07 18:24:22
C#与C++ dll之间传递字符串string wchar_t* char* IntPtr问题
2022-09-16 09:34:53
InterProcessMutex实现zookeeper分布式锁原理
2023-08-11 05:46:43
springboot v2.0.3版本多数据源配置方法
2023-07-27 06:37:57
android 版本检测 Android程序的版本检测与更新实现介绍
2022-12-02 11:27:41