介绍C# ArrayList

 

 
  • 摘要:本文介绍C# ArrayList又被称为动态数组,它的存储空间可以被动态改变,同时还拥有添加、删除元素的功能。
    如果要动态地改变数组所占用内存空间的大小,则需以数组为基础进一步抽象,以实现这个功能。

    现实中,为了让一个班新加入的10个学生能跟原来的学生住在一起而把班级整体搬迁,这样的做法显示不合适,因为搬迁的成本太高。但在计算机中,内存成片区域间的拷贝成本是非常低的,这样的解决方案是合理可行的。

    但是这个解决方案还存在问题,如果一个班级频繁地有新学生加入,为了保证学生能住在连续的宿舍内,整个班级就不得不频繁地搬迁。可以采用以空间换时间的做法来解决这个问题,在学生每次搬迁时,都让班级宿舍的数量是原来的两倍。也就是说,如果原来一个班级有4间宿舍,搬迁后就变为8间,再次搬迁则变为16 间。

    C# ArrayList正是采用上述方法来动态改变数组大小的。C# ArrayList又被称为动态数组,它的存储空间可以被动态改变,同时还拥有添加、删除元素的功能。

    下面列出了C# ArrayList的部分核心代码:

  1. using System;
  2. namespace LinearList
  3. {
  4. public class ArrayList
  5. {
  6. // 成员变量
  7. private const int _defaultCapacity = 4; //默认初始容量
  8. private object[] _items; //用于存放元素的数组
  9. private int _size; //指示当前元素个数
  10. //当元素个数为零时的数组状态
  11. private static readonly object[] emptyArray = new object[0];
  12. // 方法
  13. public ArrayList() //默认构造方法
  14. { //这样做可以避免元素个数为零时的访问出错
  15. this._items = emptyArray;
  16. }
  17. //指定ArrayList初始容量的构造方法
  18. public ArrayList(int capacity)
  19. {
  20. if (capacity <0)
  21. { //当容量参数为负数时引发异常
  22. throw new ArgumentOutOfRangeException("capacity",
  23. "为ArrayList指定的初始容量不能为负数");
  24. }
  25. //按照capacity参数指定的长度的值初始化数组
  26. this._items = new object[capacity];
  27. }
  28. //添加一个方法
  29. public virtual int Add(object value)
  30. { //当空间满时
  31. if (this._size == this._items.Length)
  32. { //调整空间
  33. this.EnsureCapacity(this._size + 1);
  34. }
  35. this._items[this._size] = value; //添加元素
  36. return this._size++; //使长度加1
  37. }
  38. //动态调整数组空间
  39. private void EnsureCapacity(int min)
  40. {
  41. if (this._items.Length <min)
  42. { //空间加倍
  43. int num = (this._items.Length == 0) ?
  44. _defaultCapacity : (this._items.Length * 2);
  45. if (num <min)
  46. {
  47. num = min;
  48. }
  49. //调用Capacity的set访问器以按照num的值调整数组空间
  50. this.Capacity = num;
  51. }
  52. }
  53. //在指定索引入插入指定元素
  54. public virtual void Insert(int index, object value)
  55. {
  56. if ((index <0) || (index > this._size))
  57. {
  58. throw new ArgumentOutOfRangeException("index", "索引超出范围");
  59. }
  60. if (this._size == this._items.Length)
  61. { //当空间满时调整空间
  62. this.EnsureCapacity(this._size + 1);
  63. }
  64. if (index <this._size)
  65. { //插入点后面的所有元素向后移动一位
  66. Array.Copy(this._items, index,
  67. this._items, index + 1, this._size - index);
  68. }
  69. this._items[index] = value; //插入元素
  70. this._size++; //使长度加1
  71. }
  72. //移除指定索引的元素
  73. public virtual void RemoveAt(int index)
  74. {
  75. if ((index <0) || (index >= this._size))
  76. {
  77. throw new ArgumentOutOfRangeException("index", "索引超出范围");
  78. }
  79. this._size--; //使长度减1
  80. if (index <this._size)
  81. { //使被删除元素后的所有元素向前移动一位
  82. Array.Copy(this._items, index + 1,
  83. this._items, index, this._size - index);
  84. }
  85. this._items[this._size] = null; //最后一位空出的元素置空
  86. }
  87. //裁减空间,使存储空间正好适合元素个数
  88. public virtual void TrimToSize()
  89. {
  90. thisthis.Capacity = this._size;
  91. }
  92. // 属性
  93. public virtual int Capacity //指示ArrayList的存储空间
  94. {
  95. get
  96. {
  97. return this._items.Length;
  98. }
  99. set
  100. {
  101. if (value != this._items.Length)
  102. {
  103. if (value <this._size)
  104. {
  105. throw new ArgumentOutOfRangeException("value", "容量太小");
  106. }
  107. if (value > 0)
  108. { //开辟一块新的内存空间存储元素
  109. object[] destinationArray = new object[value];
  110. if (this._size > 0)
  111. { //把元素搬迁到新空间内
  112. Array.Copy(this._items, 0,
  113. destinationArray, 0, this._size);
  114. }
  115. this._items = destinationArray;
  116. }
  117. else //最小空间为_defaultCapacity所指定的数目,这里是4
  118. {
  119. this._items = new object[_defaultCapacity];
  120. }
  121. }
  122. }
  123. }
  124. public virtual int Count //只读属性,指示当前元素个数
  125. {
  126. get
  127. {
  128. return this._size;
  129. }
  130. }
  131. public virtual object this[int index] //索引器
  132. {
  133. get //获取指定索引的元素值
  134. {
  135. if ((index <0) || (index >= this._size))
  136. {
  137. throw new ArgumentOutOfRangeException("index", "索引超出范围");
  138. }
  139. return this._items[index];
  140. }
  141. set //设置指定索引的元素值
  142. {
  143. if ((index <0) || (index >= this._size))
  144. {
  145. throw new ArgumentOutOfRangeException("index", "索引超出范围");
  146. }
  147. this._items[index] = value;
  148. }
  149. }
  150. }
  151. }
原文地址:https://www.cnblogs.com/fjsnail/p/2626240.html