網站首頁 編程語言 正文
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
相關推薦
- 2022-04-03 django中websocket的具體使用_python
- 2022-08-16 C#?IEnumerator枚舉器的具體使用_C#教程
- 2022-05-11 continue,return,break的區別
- 2022-05-18 Golang?并發下的問題定位及解決方案_Golang
- 2022-08-25 如何使用Python修改matplotlib.pyplot.colorbar的位置以對齊主圖_pyt
- 2022-09-24 關于R語言包的升級與降級問題_R語言
- 2023-04-02 GoLang調用鏈可視化go-callvis使用介紹_Golang
- 2022-10-22 C++11新增的包裝器詳解_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支