2020年10月7日 星期三

小山的 C# 教學 - 第 49 課 - 串列 (List)

本課簡介

本課介紹了 C# 中常見的資料結構 - 串列 (List)
串列為非常基礎且易於使用的一種資料結構
可以根據儲存的資料量動態調整所需的記憶體空間
因此常替代陣列用來暫存大量的資料

另外本課也稍微介紹了泛型 (Generics)
讓大家了解如何指定串列 (List) 之中要儲存何種型別的資料


教學影片

注意:影片有高畫質 720P 的選項,可以看得更清楚喔!


重點提示
  1. 陣列不太好用,因為:
    1. 陣列長度是固定的,且要預先設定
    2. 陣列建立後沒用的空間就浪費掉了
  2. List<T> 是類似陣列 (Array) 的資料結構,但是長度可以隨存放的物件數量調整
  3. List<T> 使用泛型 (Generics) 語法來指定存放物件的型別,必須在建立 List<T> 物件時把 T 換成要儲存的型別
  4. 本課介紹的 List<T> method:
    1. 加入物件 x :list.Add(x)
    2. 取得 pos 位置的物件:list[pos]
    3. 刪除 pos 位置的物件:list.RemoveAt(pos)
    4. 取得現在有幾個物件:list.Count
    5. 刪除物件 x :list.Remove(x)
    6. 檢查是否存在物件 x :list.Contains(x)
    7. 排序裡面的物件:list.Sort()

課程補充

List 的 Remove 與 Contains 判斷相等的方式

在課程中有提到,在呼叫 List 的 Remove 與 Contains 時,List 必須要一個個比較給予的物件是否與裡面存的物件相等。 那這個相等是怎麼判斷的呢?雖然數值的「相等」感覺很直覺,例如兩個 int 的值只要相同應該就是相等。 但是那如果是自己定義的 class,要怎麼進行判斷?

List 判斷的邏輯如右:他會先檢查該 class 是否有實作 IEquatable<T> 這個介面 (怎麼又有泛型啊?)。 如果有實作的話,該 class 應該會包含 Equals(T y) 這個 method。 此時 List 就會呼叫這個 method 判斷相等。 如果沒有實作的話,就會呼叫每個物件預設都會有的 Equals(Object obj) 這個 method。 這兩個 Equals 看似相同,但實際上第一個 Equals 只接受跟自己相同型別或衍生型別的物件,第二個則接受所有種類的物件。 因此後者的泛用性比較高。

那這個預設的 Equals(Object obj) 又怎麼判斷? 其實他的判斷很簡單,就是檢查兩個物件是否為同一個物件! 而不會去檢查裡面的數值是否相同。 換句話說,如果有兩個物件裡面都只有一個整數變數,且值都為 1。 但因為這是兩個分開的物件,所以呼叫 Equals(Object obj) 還是會判斷是不同的東西。 這個行為可以透過 override Equals(Object obj) 來改變,進而訂定自己判斷相同的做法。

List 的 Sort 如何比較大小?

為了要比較兩個物件的大小,物件必須也要提供某種 method 來進行判斷。 因此 List 要求所有要進行 Sort 的物件必須實作 IComparable<T> 這個介面,或者外面必須要另外傳入一種有實作 IComparer<T> 介面的工具用來比較。 如果這兩種東西都沒提供,系統就會直接在執行到該行時報錯。 IComparable<T> 的內容很簡單,裡面只有 CompareTo(T) 這個 method。 如果一個物件 x 有提供這個 method 的話,我只要呼叫 x.CompareTo(y) 就可以知道誰大誰小。 如果傳回的值是負的,代表 x 較小;如果值是正的,代表 x 較大;如果值相同,代表 x 跟 y 一樣大。

相關資訊連結


沒有留言:

張貼留言