瞭解了ICollection介面、迭代以及泛型集合,下面再詳細瞭解一下IList介面。
通過MSDN可以看到IList介面有兩種:
元素為object類型的IList介面,可以放不同類型的對象引用;
IList<T>泛型介面,只能存放指定類型的對象引用。
其實,IList和IList<T>也稱之為向量,特點是可以動態改變集合的長度,無需確定集合的初始長度,集合會隨著存放資料的數量自動變化。
可以看到IList和IList<T>的繼承關係:
[ComVisibleAttribute(true)]public interface IList : ICollection, IEnumerablepublic interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable
現在再返回去看下,IList和IList<T>的區別,看如下代碼,ArrayList是繼承IList的,List繼承IList<T>:
public class IListClass { void test() { TestClass1 c1 = null; ArrayList arryList = new ArrayList(); arryList.Add(c1); List<TestClass1> list = new List<TestClass1>(); list.Add(c1); //取值 TestClass1 getC1Array = arryList[0] as TestClass1;//必須要一次強制轉換 TestClass1 getC1List = list[0];//不需要轉換,所謂泛型 } } public class TestClass1 { }
這下就比較明白了。
一、IList介面概述
ILis介面從ICollection介面繼承,具備以下特性,
Count屬性——擷取集合元素個數;
GetEnumerator方法——可以迭代;
CopyTo方法——將指定元素複製到另一個數組中;
Clear方法——清空整個集合。
IList新增特性,
索引器屬性——根據索引訪問集合中任意元素;
Add方法——向集合末尾添加元素;
Insert方法——向集合指定位置插入元素;
Remove方法——移除指定元素;(包括RemoveAt)
Contains方法——判斷對象是否在集合中;
IndexOf方法——尋找指定對象在集合中的索引位置。
另外,IList介面集合按照順序存放元素,不改變元素存放順序。
2、演算法
向量集合和數組一樣,具備隨即訪問的特點。即無論訪問向量集合的任何一個單元,所需的訪問時間是完全相同的。在向量類中,實際上依然使用普通數組來記錄集合資料,向量類使用了一些演算法技巧,讓整個類對外表現不同於普通數組的重要特點:可以動態改變數組長度。具體演算法如下:
在內部數組足夠長的情況下,直接進行添加和插入操作,在內部數組長度不足的情況下,按照內部數組長度增加2倍作為新的數組的長度,然後進行資料搬移(即把就數組數組移到新數組中)。向量在分配元素儲存空間時,會多分配一些冗餘空間,盡量減少記憶體配置次數。在資料刪除時,並不改變內部數組長度,僅僅是使用被刪除資料之後的資料覆蓋被刪除的資料。
不過向量每次分配空間時都多分配一些冗餘空間,會造成記憶體的壓力,因此在程式中應該盡量避免集中的次數繁多的記憶體配置。
三、實作類別
IList和IList<T>的實作類別,分別是ArrayList類和List<T>類。
ArrayList類處於System.Collection命名空間下;
List<T>類處於System.Collection.Specialized命名空間下。
四、實現代碼(非泛型)
/// <summary> /// 實現IList,非泛型 /// </summary> public class ArrayList : IList { /// <summary> /// 迭代 /// </summary> public struct Enumertor : IEnumerator { /// <summary> /// 迭代索引 /// </summary> private int index; /// <summary> /// 迭代器所屬的向量類對象的引用 /// </summary> private ArrayList arrayList; /// <summary> /// 建構函式 /// </summary> /// <param name="arrayList">迭代器所屬的集合類</param> public Enumertor(ArrayList arrayList) { this.arrayList = arrayList; this.index = -1; } /// <summary> /// 擷取當前對象,根據index的值返迴向量對應的對象引用 /// </summary> public object Current { get { return arrayList[index]; } } /// <summary> /// 將迭代器指向下一個資料位元置,通過改變index的值,加1或減1 /// </summary> /// <returns></returns> public bool MoveNext() { if (this.index < arrayList.Count) { ++this.index; } return this.index < arrayList.Count; } /// <summary> /// 迭代器回到起始位置,將index置為-1 /// </summary> public void Reset() { this.index = -1; } } /// <summary> /// 儲存集合的數組 /// </summary> private object[] array = new object[1]; /// <summary> /// 當前集合的長度 /// </summary> private int count; /// <summary> /// 預設建構函式 /// </summary> public ArrayList() { } /// <summary> /// 參數建構函式,通過參數指定內部數組長度,減少重新分配空間 /// </summary> /// <param name="capacity"></param> public ArrayList(int capacity) { if (capacity < 0) { throw new Exception(); } if (capacity == 0) { capacity = 1; } this.array = new object[capacity]; this.count = 0; } public int Count { get { return this.count;//該屬性唯讀 } } /// <summary> /// 集合實際使用長度 /// </summary> public int Capacity { get { return this.array.Length; } } /// <summary> /// 是否固定大小 /// </summary> public bool IsFixedSize { get { return false; } } /// <summary> /// 是否唯讀集合 /// </summary> public bool IsReadOnly { get { return false; } } /// <summary> /// 是否同步,即是否支援多線程訪問 /// </summary> public bool IsSynchronized { get { return false; } } /// <summary> /// 同步對象 /// </summary> public object SyncRoot { get { return null; } } /// <summary> /// 當array長度不足時,重新分配新的長度足夠的數組 /// </summary> /// <returns></returns> private object[] GetNewArray() { return new object[(this.array.Length + 1) * 2]; } public int Add(object value) { int newCount = this.count + 1; if (this.array.Length < newCount)//長度不足 { object[] newArray = GetNewArray(); Array.Copy(this.array, newArray, this.count); this.array = newArray;//重新引用,指向新數組 } //增加新元素 this.array[this.count] = value; this.count = newCount; //返回新元素的索引位置 return this.count - 1; } /// <summary> /// 索引器屬性,按索引返迴向量中的某一項 /// </summary> /// <param name="index"></param> /// <returns></returns> public object this[int index] { get { if (index < 0 || index >= this.count) { throw new Exception(); } return this.array[index]; } set { if (index < 0 || index >= this.count) { throw new Exception(); } this.array[index] = value; } } /// <summary> /// 刪除集合中的元素 /// </summary> /// <param name="index"></param> /// <param name="count"></param> public void RemoveRange(int index, int count) { if (index < 0) { throw new Exception(); } int removeIndex = index + count;//計算集合中最後一個被刪元素的索引 if (count < 0 || removeIndex > this.count) { throw new Exception(); } //刪除其實是將要刪除元素之後的所有元素拷貝到要刪除元素的位置覆蓋掉 Array.Copy(this.array, index + 1, this.array, index + count - 1, this.count - removeIndex); //重新設定集合長度 this.count -= count; } /// <summary> /// 尋找對應的數組項,實際是遍曆尋找 /// </summary> /// <param name="value"></param> /// <returns></returns> public int IndexOf(object value) { int index = 0; if (value == null) { while (index < this.count) { if (this.array[index] == null) { return index; } ++index; } } else { while (index < this.count) { if (this.array[index].Equals(value)) { return index; } ++index; } } return -1; } /// <summary> /// 從集合中刪除指定元素 /// </summary> /// <param name="value"></param> public void Remove(object value) { int index = this.IndexOf(value); if (index >= 0) { this.RemoveRange(index, 1); } } /// <summary> /// 從集合中刪除指定位置的元素 /// </summary> /// <param name="index"></param> public void RemoveAt(int index) { RemoveRange(index, 1); } /// <summary> /// 擷取最後一個元素的引用後刪除最後一個元素 /// </summary> /// <returns></returns> public object PopBack() { object obj = this.array[this.count - 1]; RemoveAt(this.count - 1); return obj; } /// <summary> /// 擷取第一個元素引用並刪除第一個元素 /// </summary> /// <returns></returns> public object PropFront() { object obj = this.array[0]; RemoveAt(0); return obj; } /// <summary> /// 插入元素 /// </summary> /// <param name="index"></param> /// <param name="value"></param> public void Insert(int index, object value) { if (index >= this.count) { throw new Exception(); } //插入元素當空間不足時也是聲明新的2倍長度數組,並拷貝舊資料。 //插入資料原理是,將指定位置後的資料全部後移,再將新資料放在指定位置。 int newCount = this.count + 1; if (this.array.Length < newCount) { object[] newArray = GetNewArray(); Array.Copy(this.array, newArray, index); this.array = newArray; } Array.Copy(this.array, index, this.array, index + 1, this.count - index); this.array[index] = value; this.count = newCount; } /// <summary> /// 查看當前集合是否包含指定對象 /// </summary> /// <param name="value"></param> /// <returns></returns> public bool Contains(object value) { return this.IndexOf(value) >= 0; } /// <summary> /// 將集合的長度改變為實際長度 /// </summary> public void TrimToSize() { //為了消除Add和Insert時增加的冗餘,原理是新產生一個和實際長度相同的數組,然後將值全部移過來。 if (this.array.Length > this.count) { object[] newArray = null; if (this.count > 0) { newArray = new object[this.count]; Array.Copy(this.array, newArray, this.count); } else { newArray = new object[1]; } this.array = newArray; } } /// <summary> /// 清空集合 /// </summary> public void Clear() { this.count = 0; } /// <summary> /// 擷取集合的迭代器 /// </summary> /// <returns></returns> public IEnumerator GetEnumerator() { Enumertor enumerator = new Enumertor(this); return enumerator; } /// <summary> /// 轉移集合元素 /// </summary> /// <param name="targetArray"></param> /// <param name="index"></param> public void CopyTo(Array targetArray, int index) { Array.Copy(this.array, 0, targetArray, index, this.count); } }
調用測試:
static void Main(string[] args) { //調用測試 ArrayList myArrayList = new ArrayList(); myArrayList.Add(40); myArrayList.Add(80); myArrayList.Add("Hello"); //使用for迴圈遍曆 for (int i = 0; i < myArrayList.Count; i++) { Console.WriteLine(myArrayList[i]); } Console.WriteLine("---------------------"); //使用迭代迴圈 foreach (object obj in myArrayList) { Console.WriteLine(obj); } Console.WriteLine("---------------------"); myArrayList.Insert(1, "Insert"); foreach (object obj in myArrayList) { Console.WriteLine(obj); } Console.WriteLine("---------------------"); myArrayList.Remove("Insert"); foreach (object obj in myArrayList) { Console.WriteLine(obj); } Console.WriteLine("---------------------"); myArrayList.RemoveAt(1); foreach (object obj in myArrayList) { Console.WriteLine(obj); } Console.WriteLine("---------------------"); myArrayList.Clear(); foreach (object obj in myArrayList) { Console.WriteLine(obj); } Console.WriteLine("---------------------"); Random rand = new Random(); for (int i = 0; i < 10; i++) { myArrayList.Add(rand.Next(10)); } foreach (object obj in myArrayList) { Console.WriteLine(obj); } Console.WriteLine("---------------------"); Console.WriteLine("集合是否包含為1的元素 ? " + (myArrayList.Contains(0) ? "包含" : "不包含")); Console.WriteLine("元素1的位置 " + myArrayList.IndexOf(1)); Console.ReadLine(); }
結果:
以上就是的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!