了解了ICollection接口、迭代以及泛型集合,下面再詳細了解一下IList接口。
通過MSDN可以看到IList接口有兩種:
元素為object類型的IList接口,可以放不同類型的對象引用;
IList<T>泛型接口,只能存放指定類型的對象引用。
其實,IList和IList<T>也稱之為向量,特點是可以動態的改變集合的長度,無需確定集合的初始長度,集合會隨著存放數據的數量自動變化。
可以看到IList和IList<T>的繼承關系:www.2cto.com
[csharp]
[ComVisibleAttribute(true)]
public interface IList : ICollection, IEnumerable
public interface IList<T> : ICollection<T>,
IEnumerable<T>, IEnumerable
[ComVisibleAttribute(true)]
public interface IList : ICollection, IEnumerable
public interface IList<T> : ICollection<T>,
IEnumerable<T>, IEnumerable現在再返回去看下,IList和IList<T>的區別,看如下代碼,ArrayList是繼承IList的,List繼承IList<T>:
[csharp]
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
{
}
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命名空間下。
四、實現代碼(非泛型)
[csharp]
/// <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);
}
}
/// <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);
}
}
調用測試:
[csharp]
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();
}
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();
}結果: