静态数组:int[]、float[]、double[] 、char[]、string[]

特点:数组一旦创建,其容量的大小是无法改变的

int[] arr = new int[20]
虽然我这边里可以提前设定好了容量,但是存储数据的一种,我们永远都想象不到会有多少数据会被进行存储,所以适当的使用动态数组,是最好的!

扩展知识(1):

image.png

首先,图片中的 this 代表正在运行的当前实例,也就是这个类的一个构造器! 最后,我们可以知道 public Array1() : this(10) Array1():this(10) 表示的是调用自己类中的另一个构造器(Array1(int capacity))

扩展知识(2):

image.png

stringBuilder** 用于字符串连接,并且效率远高于string “+”将整数类型进行拼接的效率要快。 StringBuilder.Append:将信息追加到当前 StringBuilder 的结尾! string.Format **

image.png

对数组进行增加、添加、修改、查询、删除的例子:

Add 函数中的 For循环是让数组的 元素通通往后移** ,然后(date[index] = e;N++;)是在数组中添加元素。 而之所以要重写 Tostring(),首先在不重写的情况下,我们输出 a ,调用的是 base.object.Tostring(),只会输出 命名空间.类名 所以重写 Tostring(),让他变为我们想要输出的结果。 代码逻辑就是:在 For 循环中添加、修改元素,然后重写 Tostring()**进行返回输出。

  1. class Array1
  2. {
  3. private int[] date;
  4. private int N;
  5. /// <summary>
  6. /// 这个构造器,让用户自己填写容量
  7. /// </summary>
  8. /// <param name="capacity">用户添加的数组容量</param>
  9. public Array1(int capacity)
  10. {
  11. date = new int[capacity];
  12. N = 0;
  13. }
  14. public Array1() : this(10) { }
  15. public int Capacity
  16. {
  17. get
  18. {
  19. return date.Length;
  20. }
  21. }
  22. public int Count
  23. {
  24. get
  25. {
  26. return N;
  27. }
  28. }
  29. public bool IsEmpty
  30. {
  31. get
  32. {
  33. return N == 0;
  34. }
  35. }
  36. public void Add(int index, int e)
  37. {
  38. if (index < 0 || index > N)
  39. {
  40. throw new ArgumentNullException("数组索引越界");
  41. }
  42. if (N == date.Length)
  43. {
  44. throw new ArgumentNullException("数组已满");
  45. }
  46. for (int i = N - 1; i >= index; i--)
  47. date[i + 1] = date[i];
  48. date[index] = e;
  49. N++;
  50. }
  51. public void AddLast(int e)
  52. {
  53. Add(N, e);
  54. }
  55. public void AddFirst(int e)
  56. {
  57. Add(0, e);
  58. }
  59. /// <summary>
  60. /// 通过索引,来获取数组的元素
  61. /// </summary>
  62. /// <param name="index">数组的长度-1</param>
  63. /// <returns></returns>
  64. public int Get(int index)
  65. {
  66. if (index < 0 || index >= N)
  67. {
  68. throw new ArgumentException("数组超出索引");
  69. }
  70. return date[index];
  71. }
  72. /// <summary>
  73. /// 获取数组的第一个元素
  74. /// </summary>
  75. /// <returns></returns>
  76. public int GetFirst()
  77. {
  78. return Get(0);
  79. }
  80. /// <summary>
  81. /// 获取数组的最后一个元素
  82. /// </summary>
  83. /// <returns></returns>
  84. public int GetLast()
  85. {
  86. return Get(N - 1);
  87. }
  88. /// <summary>
  89. /// 更改指定的数组元素
  90. /// </summary>
  91. /// <param name="index">索引</param>
  92. /// <param name="newE">修改的数字</param>
  93. /// <returns></returns>
  94. public int Set(int index, int newE)
  95. {
  96. if (index < 0 || index >= N)
  97. {
  98. throw new ArgumentException("数组超出索引");
  99. }
  100. return date[index] = newE;
  101. }
  102. /// <summary>
  103. /// 查看是否有传进来的值
  104. /// </summary>
  105. /// <param name="e"></param>
  106. /// <returns></returns>
  107. public bool GetNumber(int e)
  108. {
  109. for (int i = 0; i < N; i++)
  110. {
  111. if (date[i] == e)
  112. {
  113. return true;
  114. }
  115. }
  116. return false;
  117. }
  118. /// <summary>
  119. /// 获取到传进来的值,当前的索引
  120. /// </summary>
  121. /// <param name="e"></param>
  122. /// <returns></returns>
  123. public int GetIndex(int e)
  124. {
  125. for (int i = 0; i < N; i++)
  126. {
  127. if (date[i] == e)
  128. {
  129. return i;
  130. }
  131. }
  132. return -1;
  133. }
  134. /// <summary>
  135. /// 删除指定的数组元素
  136. /// </summary>
  137. /// <param name="index"></param>
  138. /// <returns></returns>
  139. public int RemoveAt(int index)
  140. {
  141. if (index < 0 || index >= N)
  142. {
  143. throw new ArgumentException("数组超出索引");
  144. }
  145. int del = date[index];
  146. for (int i = index; i < N; i++)
  147. date[i] = date[i + 1];
  148. N--;
  149. date[N] = default(int);
  150. return del;
  151. }
  152. public int RemoveFirst()
  153. {
  154. return RemoveAt(0);
  155. }
  156. public int RemoveLast()
  157. {
  158. return RemoveAt(N - 1);
  159. }
  160. /// <summary>
  161. /// 删除指定元素的索引
  162. /// </summary>
  163. /// <param name="e"></param>
  164. public void Remove(int e)
  165. {
  166. int index = date[e];
  167. if (index != -1)
  168. {
  169. RemoveAt(index);
  170. }
  171. }
  172. public override string ToString()
  173. {
  174. StringBuilder res = new StringBuilder();
  175. res.Append(string.Format("Array1:count = {0} capacity = {1}\n", N, date.Length));
  176. res.Append("[");
  177. for (int i = 0; i < N; i++)
  178. {
  179. res.Append(date[i]);
  180. if (i != N - 1)
  181. res.Append(",");
  182. }
  183. res.Append("]");
  184. return res.ToString();
  185. }
  186. }
  187. class Program
  188. {
  189. private static void Main(string[] args)
  190. {
  191. Array1 a = new Array1(20);
  192. for (int i = 0; i < 10; i++)
  193. {
  194. a.AddLast(i);
  195. }
  196. Console.WriteLine(a);
  197. a.AddFirst(66);
  198. Console.WriteLine(a);
  199. a.Add(2, 77);
  200. Console.WriteLine(a);
  201. Console.WriteLine("==========分隔符===========");
  202. Console.WriteLine(a.Get(8));
  203. Console.WriteLine(a.GetFirst());
  204. Console.WriteLine(a.GetLast());
  205. a.Set(1, 200);
  206. Console.WriteLine(a);
  207. Console.WriteLine("==========分隔符===========");
  208. Console.WriteLine(a.GetNumber(5));
  209. Console.WriteLine(a.RemoveAt(5));
  210. Console.WriteLine(a.GetIndex(9));
  211. Console.WriteLine(a);
  212. Console.WriteLine("==========分隔符===========");
  213. a.RemoveAt(2);
  214. a.RemoveFirst();
  215. a.RemoveLast();
  216. a.Remove(4);
  217. Console.WriteLine(a);
  218. Console.ReadKey();
  219. }
  220. }

运行结果:

image.png


动态数组:

特点:可以根据元素的多少动态地调整数组容量的大小,就算先前设置好容量,我们再次进行添加数据,因为动态数组具有自动扩容的能力
缺点:我们总是未能充分使用到动态数组的空间。


动态数组的例子:

通过计算当前数组的元素是否为原来的四分之一,进行缩容 是否为超出原来的数组容量,进行扩容

  1. class Array1{
  2. public void Add(int index, int e)
  3. {
  4. if (index < 0 || index > N)
  5. {
  6. throw new ArgumentNullException("数组索引越界");
  7. }
  8. if (N == date.Length)
  9. {
  10. ResetCapacity(2 * date.Length);
  11. }
  12. for (int i = N - 1; i >= index; i--)
  13. date[i + 1] = date[i];
  14. date[index] = e;
  15. N++;
  16. }
  17. /// <summary>
  18. /// 删除指定的数组元素
  19. /// </summary>
  20. /// <param name="index"></param>
  21. /// <returns></returns>
  22. public int RemoveAt(int index)
  23. {
  24. if (index < 0 || index >= N)
  25. {
  26. throw new ArgumentException("数组超出索引");
  27. }
  28. int del = date[index];
  29. for (int i = index; i < N; i++)
  30. date[i] = date[i + 1];
  31. N--;
  32. date[N] = default(int);
  33. if (N == date.Length / 4)
  34. {
  35. ResetCapacity(date.Length / 2);
  36. }
  37. return del;
  38. }
  39. }
  40. class Program
  41. {
  42. private static void Main(string[] args)
  43. {
  44. Array1 a = new Array1(10);
  45. for (int i = 0; i < 10; i++)
  46. {
  47. a.AddLast(i);
  48. }
  49. Console.WriteLine(a);
  50. a.AddLast(100);
  51. Console.WriteLine(a) ;
  52. for (int i = 0; i < 6; i++)
  53. {
  54. a.RemoveLast();
  55. Console.WriteLine(a);
  56. }
  57. Console.ReadKey();
  58. }
  59. }

运行结果:

image.png


ArrayList、List(泛型)

泛型和非泛型的例子:

泛型和非泛型 泛型数组List有两个优势: 第一个是对于存储值类型数据,性能更优 第二个是使代码更清晰和保证类型安全 List l = newList(); ArrayList a = nwe ArrayList();

  1. class Program
  2. {
  3. private static void Main(string[] args)
  4. {
  5. int n = 10000000;
  6. Stopwatch t1 = new Stopwatch();
  7. Stopwatch t2 = new Stopwatch();
  8. Stopwatch t3 = new Stopwatch();
  9. Stopwatch t4 = new Stopwatch();
  10. Console.WriteLine("测试值类型对象int");
  11. t1.Start();
  12. List<int> l = new List<int>();
  13. for (int i = 0; i < n; i++)
  14. {
  15. l.Add(i); //不发生装箱
  16. int x = l[i]; //不发生拆箱
  17. }
  18. t1.Stop();
  19. Console.WriteLine("List'Time:" + t1.ElapsedMilliseconds+"ms");
  20. t2.Start();
  21. ArrayList a = new ArrayList();
  22. for (int i = 0; i < n; i++)
  23. {
  24. a.Add(i); //发生装箱
  25. int x = (int)a[i]; //发生拆箱
  26. }
  27. t2.Stop();
  28. Console.WriteLine("List'Time:" + t2.ElapsedMilliseconds + "ms");
  29. Console.WriteLine("测试引用类型对象string");
  30. t3.Start();
  31. List<string> l2 = new List<string>();
  32. for (int i = 0; i < n; i++)
  33. {
  34. l2.Add("X"); //不发生装箱
  35. string x = l2[i]; //不发生拆箱
  36. }
  37. t3.Stop();
  38. Console.WriteLine("List'Time:" + t3.ElapsedMilliseconds + "ms");
  39. t4.Start();
  40. ArrayList a2 = new ArrayList();
  41. for (int i = 0; i < n; i++)
  42. {
  43. a2.Add("x"); //不发生装箱
  44. string x = (string)a2[i]; //不发生拆箱
  45. }
  46. t4.Stop();
  47. Console.WriteLine("List'Time:" + t4.ElapsedMilliseconds + "ms");
  48. Console.ReadKey();
  49. }
  50. }

运行结果:

image.png

运用泛型对动态数组添加元素的例子:

  1. class Array1<T>
  2. {
  3. private T[] date;
  4. private int N;
  5. /// <summary>
  6. /// 这个构造器,让用户自己填写容量
  7. /// </summary>
  8. /// <param name="capacity">用户添加的数组容量</param>
  9. public Array1(int capacity)
  10. {
  11. date = new T[capacity];
  12. N = 0;
  13. }
  14. public Array1() : this(10) { }
  15. public int Capacity
  16. {
  17. get
  18. {
  19. return date.Length;
  20. }
  21. }
  22. public int Count
  23. {
  24. get
  25. {
  26. return N;
  27. }
  28. }
  29. public bool IsEmpty
  30. {
  31. get
  32. {
  33. return N == 0;
  34. }
  35. }
  36. public void Add(int index, T e)
  37. {
  38. if (index < 0 || index > N)
  39. {
  40. throw new ArgumentNullException("数组索引越界");
  41. }
  42. if (N == date.Length)
  43. {
  44. ResetCapacity(2 * date.Length);
  45. }
  46. for (int i = N - 1; i >= index; i--)
  47. date[i + 1] = date[i];
  48. date[index] = e;
  49. N++;
  50. }
  51. public void AddLast(T e)
  52. {
  53. Add(N, e);
  54. }
  55. public void AddFirst(T e)
  56. {
  57. Add(0, e);
  58. }
  59. /// <summary>
  60. /// 通过索引,来获取数组的元素
  61. /// </summary>
  62. /// <param name="index">数组的长度-1</param>
  63. /// <returns></returns>
  64. public T Get(int index)
  65. {
  66. if (index < 0 || index >= N)
  67. {
  68. throw new ArgumentException("数组超出索引");
  69. }
  70. return date[index];
  71. }
  72. /// <summary>
  73. /// 获取数组的第一个元素
  74. /// </summary>
  75. /// <returns></returns>
  76. public T GetFirst()
  77. {
  78. return Get(0);
  79. }
  80. /// <summary>
  81. /// 获取数组的最后一个元素
  82. /// </summary>
  83. /// <returns></returns>
  84. public T GetLast()
  85. {
  86. return Get(N - 1);
  87. }
  88. /// <summary>
  89. /// 更改指定的数组元素
  90. /// </summary>
  91. /// <param name="index">索引</param>
  92. /// <param name="newE">修改的数字</param>
  93. /// <returns></returns>
  94. public void Set(int index, T newE)
  95. {
  96. if (index < 0 || index >= N)
  97. {
  98. throw new ArgumentException("数组超出索引");
  99. }
  100. date[index] = newE;
  101. }
  102. /// <summary>
  103. /// 查看是否有传进来的值
  104. /// </summary>
  105. /// <param name="e"></param>
  106. /// <returns></returns>
  107. public bool GetNumber(int e)
  108. {
  109. for (int i = 0; i < N; i++)
  110. {
  111. if (date[i].Equals(e))
  112. {
  113. return true;
  114. }
  115. }
  116. return false;
  117. }
  118. /// <summary>
  119. /// 获取到传进来的值,当前的索引
  120. /// </summary>
  121. /// <param name="e"></param>
  122. /// <returns></returns>
  123. public int GetIndex(int e)
  124. {
  125. for (int i = 0; i < N; i++)
  126. {
  127. if (date[i].Equals(e))
  128. {
  129. return i;
  130. }
  131. }
  132. return -1;
  133. }
  134. /// <summary>
  135. /// 删除指定的数组元素
  136. /// </summary>
  137. /// <param name="index"></param>
  138. /// <returns></returns>
  139. public T RemoveAt(int index)
  140. {
  141. if (index < 0 || index >= N)
  142. {
  143. throw new ArgumentException("数组超出索引");
  144. }
  145. T del = date[index];
  146. for (int i = index; i < N; i++)
  147. date[i] = date[i + 1];
  148. N--;
  149. date[N] = default(T);
  150. if (N == date.Length / 4)
  151. {
  152. ResetCapacity(date.Length / 2);
  153. }
  154. return del;
  155. }
  156. public T RemoveFirst()
  157. {
  158. return RemoveAt(0);
  159. }
  160. public T RemoveLast()
  161. {
  162. return RemoveAt(N - 1);
  163. }
  164. /// <summary>
  165. /// 删除指定元素的索引
  166. /// </summary>
  167. /// <param name="e"></param>
  168. public void Remove(int e)
  169. {
  170. int index = e;
  171. if (index != -1)
  172. {
  173. RemoveAt(index);
  174. }
  175. }
  176. private void ResetCapacity(int newCapcaity)
  177. {
  178. T[] newDate = new T[newCapcaity];
  179. for (int i = 0; i < N; i++)
  180. newDate[i] = date[i];
  181. date = newDate;
  182. }
  183. public override string ToString()
  184. {
  185. StringBuilder res = new StringBuilder();
  186. res.Append(string.Format("Array1:count = {0} capacity = {1}\n", N, date.Length));
  187. res.Append("[");
  188. for (int i = 0; i < N; i++)
  189. {
  190. res.Append(date[i]);
  191. if (i != N - 1)
  192. res.Append(",");
  193. }
  194. res.Append("]");
  195. return res.ToString();
  196. }
  197. }
  198. class Program
  199. {
  200. private static void Main(string[] args)
  201. {
  202. int[] n = { 1, 2, 3, 4, 5, 6, 7 };
  203. Array1<int> a = new Array1<int>();
  204. for (int i = 0; i < n.Length; i++)
  205. a.AddLast(n[i]);
  206. Console.WriteLine(a);
  207. string[] s = { "1","2","3","4","5" };
  208. Array1<string> a1 = new Array1<string>();
  209. for (int i = 0; i < s.Length; i++)
  210. a1.AddLast(s[i]);
  211. Console.WriteLine(a1);
  212. Console.ReadKey();
  213. }
  214. }

运行结果:

image.png