基本概念

数组(Array)是有序的元素序列。
若将有限个类型相同的变量的集合命名,那么这个名称为数组名。
组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。
用于区分数组的各个元素的数字编号称为下标。

数组本身属于引用类型,使用前要开辟空间,否则访问会抛 NullPointerException

数组动态初始化

  • 声明并分配空间: int[] list = new int[10];
  • 分布开辟空间:int[] list = null; list = new int[10];

静态初始化

  • int[] data = {1, 2, 3, 4};
  • 匿名数组: System.out.println(Arrays.toString(new int[]{1, 2, 3, 4}));

数组的索引 从 0 到 size - 1,如果索引访问不在此范围内,会抛出 ArrayIndexOutOfBoundsException

数组采用动态初始化开辟空间后,数组里面每一个元素都是该数组对应数据类型的默认类型
image.png

数组的二次封装

  1. public class Array<E> {
  2. private E[] data;
  3. private int size;
  4. public Array(int capacity) {
  5. data = (E[])new Object[capacity];
  6. size = 0;
  7. }
  8. public Array() {
  9. this(10);
  10. }
  11. public int getSize() {
  12. return size;
  13. }
  14. public int getCapacity() {
  15. return data.length;
  16. }
  17. public boolean isEmpty() {
  18. return size == 0;
  19. }
  20. public void addLast(E e) {
  21. add(size, e);
  22. }
  23. public void addFirst(E e) {
  24. add(0, e);
  25. }
  26. public void add(int index, E e) {
  27. if (index < 0 || index > size) {
  28. throw new IllegalArgumentException("Add failed, Required index < 0 || index > size");
  29. }
  30. if (size == data.length) {
  31. resize((int) (1.5 * data.length));
  32. }
  33. for (int i = size - 1 ; i >= index ; i --) {
  34. data[i + 1] = data[i];
  35. }
  36. data[index] = e;
  37. size ++;
  38. }
  39. public E get(int index) {
  40. if (index < 0 || index >= size) {
  41. throw new IllegalArgumentException("Get failed");
  42. }
  43. return data[index];
  44. }
  45. public E getLast() {
  46. return get(size - 1);
  47. }
  48. public E getFirst() {
  49. return get(0);
  50. }
  51. public void set(int index, E e) {
  52. if (index < 0 || index >= size) {
  53. throw new IllegalArgumentException("Set failed");
  54. }
  55. data[index] = e;
  56. }
  57. public boolean contains(E e) {
  58. for (int i = 0; i< size; i++) {
  59. if (data[i] == e) {
  60. return true;
  61. }
  62. }
  63. return false;
  64. }
  65. public int find(E e) {
  66. for (int i = 0; i< size; i++) {
  67. if (data[i].equals(e)) {
  68. return i;
  69. }
  70. }
  71. return -1;
  72. }
  73. public E remove(int index) {
  74. if (index < 0 || index >= size) {
  75. throw new IllegalArgumentException("Set failed");
  76. }
  77. E ret = data[index];
  78. for (int i = index; i < size - 1; i++) {
  79. data[i] = data[i + 1];
  80. }
  81. size --;
  82. data[size] = null;
  83. // 防止复杂度震荡,四分之一时再触发缩容机制
  84. if (size == data.length / 4 && data.length / 2 != 0) {
  85. resize(data.length / 2);
  86. }
  87. return ret;
  88. }
  89. public E removeFirst() {
  90. return remove(0);
  91. }
  92. public E removeLast() {
  93. return remove(size - 1);
  94. }
  95. public void removeElement(E e) {
  96. int index = find(e);
  97. if (index != -1) {
  98. remove(index);
  99. }
  100. }
  101. @Override
  102. public String toString() {
  103. StringBuilder res = new StringBuilder();
  104. res.append(String.format("Array: size = %d, capacity = %d\n", size, data.length));
  105. res.append('[');
  106. for (int i = 0; i < size; i ++) {
  107. res.append(data[i]);
  108. if (i != size - 1) {
  109. res.append(", ");
  110. }
  111. }
  112. res.append(']');
  113. return res.toString();
  114. }
  115. private void resize(int newCapacity) {
  116. E[] newData = (E[])new Object[newCapacity];
  117. for (int i = 0; i < size ;i ++) {
  118. newData[i] = data[i];
  119. }
  120. data = newData;
  121. }
  122. }