CodeGym /課程 /C# SELF /清單: List<T>

清單: List<T>

C# SELF
等級 27, 課堂 2
開放

1. 前言

想像一下你在寫購物清單。今天你要買 3 樣東西,明天 10 樣,後天只買一樣。如果你用陣列,每次都要新建一個剛好夠用的陣列。或者你乾脆建一個超大的陣列「以防萬一」,結果裡面一堆空格。這樣其實很沒效率,對吧?

現在想像你有一個魔法背包,你放東西進去它會自動變大,拿東西出來它又會縮小。你不用事先知道會放幾樣東西。你只要一直放,背包自己會調整。這就是 C# 世界裡的 List<T> 啦!

List<T> 是一種泛型集合,可以存放某種型別的元素序列。重點是 「動態」。跟陣列不一樣,List<T> 可以在程式執行時改變大小。它會自己管理內部容量,需要時自動擴充。

那 T 是什麼意思?它是所謂的型別參數。你建立 List 時,要指定它要存什麼型別的資料來取代 T。像 List<int> 只能存整數,List<string> 只能存字串,List<double> 只能存小數。這樣你就不會不小心把蘋果丟進橘子清單,對程式的穩定跟可預測性很重要。

這有什麼用?

在實際專案裡,常常你根本不知道會有幾個元素。比如說:

  • 登入網站的使用者清單。
  • 網路商店購物車裡的商品清單。
  • 搜尋結果的清單。
  • 排程器裡的任務清單,這就是我們現在要做的。

這些情況下元素數量都會變,List<T> 就是我們的好幫手啦。

List<T> 主要方法

方法 說明 範例
Add(T item)
把元素加到清單最後面
numbers.Add(5);
Insert(int idx, T)
插入到指定位置
numbers.Insert(0, 42);
Remove(T item)
刪掉第一個出現的元素
numbers.Remove(100);
RemoveAt(int idx)
用索引刪掉元素
numbers.RemoveAt(2);
Clear()
清空清單
numbers.Clear();
Contains(T item)
檢查清單裡有沒有這個元素
numbers.Contains(10);
IndexOf(T item)
第一個出現的索引
int pos = numbers.IndexOf(42);
Count
清單裡的元素數量
int n = numbers.Count;
Capacity
內部緩衝區容量
numbers.Capacity = 100;

2. 建立清單 (List<T>)

來實作一下吧!假設我們要做一個簡單的任務管理器,需要一個清單來存我們的待辦事項。

要建立新的 List<T>,用 new,跟建立其他物件一樣。

怎麼宣告跟建立 List

建立清單的語法跟陣列很像,只是用尖括號不是中括號:

using System.Collections.Generic;

List<int> numbers = new List<int>();

給愛細節的同學:
- List<int> 是整數清單(int)。你也可以用 string、double、自訂類別等等。
- 剛建立時清單是空的,長度是 0。

範例:我們 app 的第一步

假設我們有個 app,讓使用者輸入名字跟年齡(還記得前幾堂課嗎)。現在我們要讓他可以存多個名字到清單,之後再處理。

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<string> names = new List<string>();

        Console.WriteLine("請輸入三個名字:");
        for (int i = 0; i < 3; i++)
        {
            string name = Console.ReadLine();
            names.Add(name);
        }

        Console.WriteLine("你輸入了:");
        foreach (string n in names)
        {
            Console.WriteLine(n);
        }
    }
}

注意 Add(),就是這個方法把新元素加進清單。這就是讓它變成動態的關鍵!

也可以直接建立有元素的清單!

List<string> planets = new List<string> { "水星", "金星", "地球" };

很方便,當你已經知道「起始成員」時。這種語法常用在測試或初始化固定資料。

3. List<T> 的基本操作

在進入進階技巧前,先來學清單的「字母表」。

加元素:Add()

用 Add() 方法就像把新東西放到架上:

List<int> numbers = new List<int>();
numbers.Add(42);
numbers.Add(100);

現在裡面是:[42, 100]

取得元素數量:Count

跟陣列不一樣,清單的屬性叫 Count,不是 Length:

int count = numbers.Count; // 會回傳 2

記得:清單用 Count,陣列跟字串用 Length。這兩個屬性很像但不一樣。

用索引存取元素

有兩種方式,本質上一樣:

int first = numbers[0]; // 42
numbers[1] = 200; // 把 100 換成 200

注意: 索引從 0 開始,跟陣列一樣。你只有三個元素時不要去存 numbers[3]!

遍歷清單元素

可以用 for 或 foreach 迴圈:

// 用 for — 需要索引時
for (int i = 0; i < numbers.Count; i++)
{
    Console.WriteLine(numbers[i]);
}

// 用 foreach — 不需要索引時
foreach (int number in numbers)
{
    Console.WriteLine(number);
}

foreach 通常比較簡單易懂,特別是對大集合。
但它不能用索引改元素,也不能直接用 break 跳出,除非你用額外的寫法。

插入元素到指定位置:Insert()

Insert() 方法可以讓你不是只加到最後,而是加到任何地方。比如加到第二個位置:

numbers.Insert(1, 55); // 把 55 插到索引 1

現在 numbers: [42, 55, 200]

刪除元素

刪除元素跟加一樣簡單:

numbers.Remove(55); // 刪掉第一個 55
numbers.RemoveAt(0); // 刪掉索引 0 的元素
numbers.Clear(); // 清空整個清單

刪除小細節:
- 如果用 Remove 刪不存在的值,沒事發生,清單不變,也不會報錯。
- Clear() 之後清單又變空了。

4. 有用的小細節

List<T> 怎麼長大?

你加元素到 List<T> 時,它不會每次都只加一點點空間。List<T> 會先預留一塊記憶體(內部容量 Capacity)。

當元素超過目前容量時,清單會分配一個更大的記憶體區塊(通常是兩倍大),然後把舊資料複製過去:


加元素 → 還放得下 → 還放得下 → 還放得下 →
新元素放不下了 → 建一個更大的陣列 → 複製資料 → 繼續加

這樣加元素會比較快,因為不是每次 Add 都要重新分配記憶體,只是偶爾才會。

var list = new List<int>();    // Capacity = 0
list.Add(1);                   // Capacity = 4
list.Add(2);                   // Capacity = 4
list.Add(3);                   // Capacity = 4
list.Add(4);                   // Capacity = 4
list.Add(5);                   // Capacity = 8 (擴充!)

Capacity vs. Count:差在哪?

  • Count — 清單裡實際有幾個元素。
  • Capacity — 內部陣列的大小。
List<int> nums = new List<int>();
Console.WriteLine(nums.Count); // 0
Console.WriteLine(nums.Capacity); // 通常是 0 或很小

nums.Add(123);
Console.WriteLine(nums.Count); // 1
Console.WriteLine(nums.Capacity); // 可能比 Count 大

nums.Capacity = 1000; // 你可以手動調大 Capacity,如果你知道會有很多元素

大部分開發者只用 Count,但如果你寫效能要求很高的程式(像遊戲或資料分析),調整 Capacity 會很有用。

5. 範例

繼續進化我們的小 app —— 這次讓使用者可以加自己喜歡的數字,然後對清單做插入、刪除、顯示、清空等操作。

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> favoriteNumbers = new List<int>();

        Console.WriteLine("請輸入你喜歡的數字(每行一個,輸入 0 結束):");
        while (true)
        {
            int num = int.Parse(Console.ReadLine());
            if (num == 0) break;
            favoriteNumbers.Add(num);
        }

        Console.WriteLine("你喜歡的數字:");
        foreach (int n in favoriteNumbers)
        {
            Console.Write(n + " ");
        }

        Console.WriteLine("\n要不要刪掉第一個數字?(y/n)");
        if (Console.ReadLine().ToLower() == "y")
        {
            favoriteNumbers.RemoveAt(0);
        }

        Console.WriteLine("現在你的清單:");
        foreach (int n in favoriteNumbers)
        {
            Console.Write(n + " ");
        }
    }
}

小提醒: 這裡我們用 int.Parse。實際專案裡最好用 int.TryParse 先檢查輸入,這樣用戶亂輸入也不會讓程式掛掉。

6. 新手常見錯誤跟「地雷」

很常見的情況:你寫一個從 0 到 List.Count 的迴圈,但在迴圈裡(像 foreach)又去改清單(加或刪元素)。千萬別這樣!高手都知道這叫「遍歷時修改集合」。通常你會馬上遇到 InvalidOperationException 例外。

錯誤範例:

foreach (int n in numbers)
{
    if (n < 0)
        numbers.Remove(n); // 砰!執行時錯誤。
}

正確做法: 先把要刪的索引或元素收集到另一個清單,或用倒著走的 for 迴圈。

2
任務
C# SELF, 等級 27, 課堂 2
上鎖
在 List 中操作字串
在 List 中操作字串
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION