首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 集合教學(一):ArrayList 動態陣列 — 自動擴容、裝箱拆箱與泛型替代

     編輯:關於C#

ArrayList 實作 IList,是 **非泛型動態陣列** 的經典實現:容量自動成長、支援插入/刪除範圍、可存放任意型別。但因 **裝箱/拆箱** 導致實值型別效能損耗,.NET 2.0+ 強烈建議改用 List<T>。

ArrayList vs 陣列 核心差異

特性陣列 T[]ArrayList
容量固定,宣告時決定動態,預設 0 → 4 → 8 → 16…(倍增)
元素型別單一型別任意型別(全部視為 object)
維度支援多維僅一維
插入/刪除需手動搬移Insert/RemoveAt/RemoveRange 內建
索引存取arr[i]al[i](同樣 O(1))

常用 API 速查

分類方法/屬性說明
容量/計數Capacity取得/設定內部陣列長度
Count實際元素數
TrimToSize()將 Capacity 縮減至 Count,釋放記憶體
新增/插入Add(obj)末尾附加
AddRange(coll)批次附加
Insert(index, obj)指定位置插入,後續元素後移
InsertRange(index, coll)批次插入
刪除Remove(obj)移除第一個相符元素
RemoveAt(index)移除指定索引
Clear()清空所有
查詢Contains(obj)線性搜尋 O(n)
IndexOf(obj) / LastIndexOf取得索引位置
排序/反轉Sort() / Sort(IComparer)QuickSort,需元素可比較
Reverse() / Reverse(index, count)就地反轉

實戰演示:基本操作與容量成長觀察


var al = new ArrayList();
Console.WriteLine($"初始 Capacity={al.Capacity}"); // 0

al.Add("Hello");  // Capacity=4
al.Add("World");
Console.WriteLine($"Count={al.Count}, Capacity={al.Capacity}"); // 2, 4

al.Insert(1, "C#"); // Hello C# World
Console.WriteLine(string.Join(" ", al));

al.Add(".");      // Capacity=4
al.Add("---");    // Capacity=8 (擴容)
Console.WriteLine($"擴容後 Capacity={al.Capacity}"); // 8

al.Remove(".");   // Count=4, Capacity=8
al.Remove("?");   // 不存在,Count 不變
al.RemoveAt(3);   // 移除索引 3
al.TrimToSize();  // Capacity=3
Console.WriteLine($"TrimToSize 後 Capacity={al.Capacity}");

al.Clear();       // Count=0, Capacity=3 (不歸零)

裝箱/拆箱效能代價


// 新增 int 123 → 裝箱
al.Add(123); // IL: box int32 → 產生 object 參考

// 讀取並運算 → 拆箱
int sum = (int)al[0] + (int)al[1]; // IL: unbox.any int32

形象比喻:把水果(實值型別)裝進大箱子(object),搬運方便但取用時得拆箱。大量運算時 GC 壓力劇增。

泛型 List<T> 完美替代

操作ArrayListList<int>
宣告var al = new ArrayList();var list = new List<int>();
新增al.Add(1);list.Add(1); // 無裝箱
讀取int x = (int)al[0];int x = list[0]; // 直接取值
遍歷foreach(object o in al)foreach(int x in list)
排序al.Sort();list.Sort();

ArrayList ↔ 陣列 互轉


// 陣列 → ArrayList
int[] arr = {1,2,3};
var al1 = new ArrayList(arr); // 建構子
var al2 = ArrayList.Adapter(arr); // 包裝視圖,修改同步反映原陣列

// ArrayList → 陣列 (需同型別)
var al = new ArrayList { "A", "B", "C" };
string[] arr2 = (string[])al.ToArray(typeof(string)); // 強型別轉換

綜合練習:樂透號碼產生器(不重複隨機數)


var al = new ArrayList();
var rnd = new Random();
while (al.Count < 7)
{
    int n = rnd.Next(1, 36);
    if (!al.Contains(n)) al.Add(n);
}
al.Sort();
foreach (var n in al) Console.Write($"{n} "); // 輸出 7 個已排序號碼

教學重點總結

  1. 動態容量:免去手動管理陣列大小,TrimToSize() 養成習慣釋放記憶體。
  2. 任意型別:靈活但犧牲型別安全與效能,**遍歷請用 object 接收**。
  3. 裝箱/拆箱:實值型別頻繁存取時效能殺手,認清 IL 差異。
  4. 現代首選:List<T> 零裝箱、強型別、效能更優,除非維護 .NET 1.x 舊碼,否則**不再使用 ArrayList**。

下一單元將介紹 Hashtable:鍵值對 O(1) 查找的經典實現。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved