[英]List<> Capacity returns more items than added
List<T>
上有一些屬性似乎與列表中的項目數有關Capacity
, Count
(作為屬性和方法出現)。 尤其是與只有Length
Array
相比,這非常令人困惑。
我正在使用List.Capacity
但它給出了意外的結果:
List <string> fruits = new List<string>();
fruits.Add("apple");
fruits.Add("orange");
fruits.Add("banana");
fruits.Add("cherry");
fruits.Add("mango");
Console.WriteLine("the List has {0} items in it.", fruits.Capacity);
運行此命令時,控制台顯示:
the List has 4 items in it.
當我僅添加5個項目時,我不明白為什么顯示的Capacity
為8。
列表的Capacity
表示列表當前為當前對象和要添加到其中的對象預留了多少內存。 列表的Count
是實際已添加到列表中的項目數。
這是MSDN中 Capacity屬性的完整說明:
容量是需要調整大小之前List<T>
可以存儲的元素數,而Count是List<T>
中實際存在的元素數。
容量始終大於或等於Count。 如果在添加元素時Count超過了Capacity,則通過在復制舊元素和添加新元素之前自動重新分配內部數組來增加容量。
可以通過調用TrimExcess()方法或顯式設置Capacity屬性來減少容量。 顯式設置Capacity的值時,還將重新分配內部數組以容納指定的容量,並復制所有元素。
檢索此屬性的值是O(1)操作; 設置該屬性是一個O(n)操作,其中n是新容量。
為了增加其他答案,在逐一添加項目時,列表的默認行為是從容量4開始,並在列表滿時將其加倍。 這說明了8的容量。
為了了解為什么它更大,您需要了解List<T>
在內部如何工作。 在內部, List<T>
使用數組(所以T[]
)存儲其內容。
該數組以4個元素的大小開始,因此等效於說T[] array = new T[4]
。 將項目添加到List<T>
,它存儲在數組中: array[0]
的第一項, array[1]
的第二項,依此類推。但是第五項不適合該array[1]
數組,因為它只有四個元素。 並且由於數組的長度在創建后無法更改,因此唯一的選擇是獲取數組的內容並將其移動到足夠大以容納第五項的新數組。 List<T>
的實現選擇每次在空間用盡時將數組緩沖區的大小加倍,因此要適合第五項,它將數組容量加倍至8。然后是16,依此類推。
關於為什么選擇加倍的選擇可能有很好的數學依據,這可能是昂貴的復制操作(不想太頻繁地分配新緩沖區)和浪費空間之間的一個很好的折衷方案。 我相信,通過加倍,內存浪費永遠不會超過50%,並且需要分配新陣列的次數從對數上減少。
容量與列表的項目數不同。 默認情況下,所有語言的實現良好的列表容器分配的內存要比保存當前條目數所需的內存更多。 這是因為在某些時候分配更大的內存塊比每次添加一項都為另一項分配內存效率更高。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.