網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
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>內(nèi)部是依靠數(shù)組_items存放數(shù)據(jù)的
private int _size; //數(shù)組的長(zhǎng)度
private int _version;
[NoSerialized]
private Object _syncRoot;
static T[] _emptyArray = new T[0];
//無參數(shù)構(gòu)造函數(shù) 把_items設(shè)置成一個(gè)空的數(shù)組
public List()
{
_items = _emptyArray;
}
//此構(gòu)造函數(shù) 給_items數(shù)組一個(gè)初始容量
public List(int capacity)
{
...
items = new T[capaicty];
}
//此構(gòu)造函數(shù) 把集合類型參數(shù)拷貝給_items數(shù)組
public List(IEnumerable<t> collection)
{
...
ICollection<t> c = collection as ICollection<t>;
if(c != null)
{
int count = c.Count; //把構(gòu)造函數(shù)集合類型參數(shù)的長(zhǎng)度賦值給臨時(shí)變量count
_items = new T[count]; //List<T>內(nèi)部維護(hù)的_items數(shù)組的長(zhǎng)度和構(gòu)造函數(shù)集合類型參數(shù)的長(zhǎng)度一致
c.CopyTo(_items, 0); //把構(gòu)造函數(shù)集合的所有元素拷貝到_items數(shù)組中去
_size = count; //_items數(shù)組的長(zhǎng)度就是構(gòu)造函數(shù)集合類型參數(shù)的長(zhǎng)度
}
else
{
_size = 0;
_items = new T[_defaultCapacity];
...
}
}
//通過設(shè)置這個(gè)屬性,改變List<t>內(nèi)部維護(hù)的_items數(shù)組的長(zhǎng)度
public int Capacity
{
get {return _items.Length; }
set {
if(value != _items.Length){ //如果當(dāng)前賦值和List<t>維護(hù)的內(nèi)部數(shù)組_items長(zhǎng)度不一致
if(value < _size){
//TODO: 處理異常
}
if(value > 0){
T[] newItems = new T[value]; //創(chuàng)建一個(gè)臨時(shí)的、新的數(shù)組,長(zhǎng)度為新的賦值
if(_size > 0){
//把臨時(shí)的、新的數(shù)組拷貝給List<t>內(nèi)部維護(hù)的數(shù)組_items,注意,這時(shí)_items的長(zhǎng)度為新的賦值
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>內(nèi)部維護(hù)的_items數(shù)組的長(zhǎng)度至少是給定的值
//如果_items數(shù)組原先的長(zhǎng)度比給定的值小,就讓_items數(shù)組的長(zhǎng)度設(shè)置為原先的長(zhǎng)度的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>內(nèi)部維護(hù)著一個(gè)數(shù)組_items,用來存放T類型的元素。
- 當(dāng)有新的T類型元素存放進(jìn)來,即調(diào)用Add(T item)方法。
- Add(T item)方法內(nèi)部調(diào)用EnsureCapacity(int min)方法確保List<T>的Capaicty屬性值至少在原先長(zhǎng)度上加1,最多是原先長(zhǎng)度的2倍。
- 在給Capacity賦值的過程中,對(duì)_items的長(zhǎng)度進(jìn)行了擴(kuò)容。
- 擴(kuò)容后,再把新的T類型元素存放進(jìn)來。
簡(jiǎn)單地說:
當(dāng)有新的元素存放到List<T>中時(shí),List<T>先對(duì)其維護(hù)的內(nèi)部數(shù)組進(jìn)行擴(kuò)容,然后再把新元素放進(jìn)來。
原文鏈接:https://www.cnblogs.com/darrenji/p/3843749.html
相關(guān)推薦
- 2022-05-10 關(guān)于react中的state整理
- 2022-05-31 Golang庫(kù)插件注冊(cè)加載機(jī)制的問題_Golang
- 2022-10-05 Python數(shù)據(jù)可視化制作全球地震散點(diǎn)圖_python
- 2022-12-07 org.apache.tomcat.util.http.fileupload.IOUtils報(bào)錯(cuò)對(duì)應(yīng)
- 2023-07-13 css對(duì)盒模型的理解
- 2022-07-12 計(jì)算SHA-1摘要值,并轉(zhuǎn)為16進(jìn)制字符串
- 2022-01-29 composer 安裝包提示內(nèi)存不足的解決辦法
- 2022-09-26 React?Native?中添加自定義字體的方法_React
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支