数组基础:
1 package cn.zcb.demo01; 2 3 public class Test { 4 public static void main(String[] args) { 5 //数组创建 和 初始化的两种方式 6 //1 7 int [] arr = new int[10]; 8 for (int i=0;i<arr.length ;i++){ 9 arr[i] = i; 10 } 11 //2 12 int [] scores = new int[] {10,20,30,40}; 13 14 //下面是两种打印方式 15 //1 16 for (int i=0;i<scores.length;i++){ 17 System.out.println(scores[i]); 18 } 19 //2 20 for (int score:scores){ 21 System.out.println(score); 22 } 23 24 25 } 26 } 27 /* 输出结果 28 10 29 20 30 30 31 40 32 10 33 20 34 30 35 40 36 * */
索引的语义:
所以可以有语义,也可以没有语义,
有语义,例如0 代表学号,
没有语义,例如0 只是代表第一个而已。
数组最大的优点是:快速查询。所以,对于数组我们最好应用在“索引有语义”的情况。我们知道我们要查的是什么。
但是并非所有的有语义的索引都适合用于数组!
例如身份证号33333333333332442444444222!
这个时候,也可以使用数组处理“索引没有语义”的情况。
下面制作属于我们自己的数组类:
1 package cn.zcb.demo01; 2 3 public class MyArray { 4 private int[] data; //数组 5 private int size; //数组实际大小, 6 //容量不用写,可以由data.length()得知 7 8 //满参构造函数 9 public MyArray(int capacity){ 10 this.data = new int[capacity]; 11 this.size = 0; //开始时 实际大小size =0 12 } 13 //空参构造器 14 public MyArray(){ 15 this(10); //如果是空参的话,调用有参构造器。默认是10 16 } 17 }
1 package cn.zcb.demo01; 2 public class MyArray { 3 private int[] data; //数组 4 private int size; //数组实际大小, 5 //容量不用写,可以由data.length()得知 6 7 //满参构造函数 8 public MyArray(int capacity){ 9 this.data = new int[capacity]; 10 this.size = 0; //开始时 实际大小size =0 11 } 12 //空参构造器 13 public MyArray(){ 14 this(10); //如果是空参的话,调用有参构造器。默认是10 15 } 16 17 //获取数组中的元素的个数 18 public int getSize(){ 19 return this.size; 20 } 21 22 //获取数组的容量 23 public int getCapacity(){ 24 return this.data.length; 25 } 26 27 //数组中是否为空 28 public boolean isEmpty(){ 29 return this.size ==0; 30 } 31 }
向我们自己的数组中添加元素(在数组末加):
1 package cn.zcb.demo01; 2 public class MyArray { 3 private int[] data; //数组 4 private int size; //数组实际大小, 5 //容量不用写,可以由data.length()得知 6 7 //满参构造函数 8 public MyArray(int capacity){ 9 this.data = new int[capacity]; 10 this.size = 0; //开始时 实际大小size =0 11 } 12 //空参构造器 13 public MyArray(){ 14 this(10); //如果是空参的话,调用有参构造器。默认是10 15 } 16 17 //获取数组中的元素的个数 18 public int getSize(){ 19 return this.size; 20 } 21 22 //获取数组的容量 23 public int getCapacity(){ 24 return this.data.length; 25 } 26 27 //数组中是否为空 28 public boolean isEmpty(){ 29 return this.size ==0; 30 } 31 32 //向 数组的末尾添加一个新元素 33 public void addLast(int num){ 34 if(size == this.data.length){ 35 //此时开辟的空间已经满了 36 //这里先抛出一个异常 37 throw new IllegalArgumentException("addLast failed.数组已经满了"); 38 } 39 this.data[size] = num; 40 size ++; //要维持数组 指针。 size 是当前数组中的个数。 41 } 42 43 44 45 }
向我们自己的数组中添加元素(在数组指定位置添加):
1 package cn.zcb.demo01; 2 public class MyArray { 3 private int[] data; //数组 4 private int size; //数组实际大小, 5 //容量不用写,可以由data.length()得知 6 7 //满参构造函数 8 public MyArray(int capacity){ 9 this.data = new int[capacity]; 10 this.size = 0; //开始时 实际大小size =0 11 } 12 //空参构造器 13 public MyArray(){ 14 this(10); //如果是空参的话,调用有参构造器。默认是10 15 } 16 17 //获取数组中的元素的个数 18 public int getSize(){ 19 return this.size; 20 } 21 22 //获取数组的容量 23 public int getCapacity(){ 24 return this.data.length; 25 } 26 27 //数组中是否为空 28 public boolean isEmpty(){ 29 return this.size ==0; 30 } 31 32 //向 数组的末尾添加一个新元素 33 public void addLast(int num){ 34 if(size == this.data.length){ 35 //此时开辟的空间已经满了 36 //这里先抛出一个异常 37 throw new IllegalArgumentException("addLast failed.数组已经满了"); 38 } 39 this.data[size] = num; 40 size ++; //要维持数组 指针。 size 是当前数组中的个数。 41 } 42 43 //向 指定数组位置添加一个新元素 44 public void insert(int idx,int num){ 45 if(this.size == this.data.length){ 46 throw new IllegalArgumentException("数组已经放满了"); 47 } 48 if(idx <0 || idx > this.size ) 49 throw new IllegalArgumentException("索引非法"); 50 51 for(int i=this.size-1;i >= idx;--i){ 52 this.data[i+1] = this.data[i]; 53 } 54 this.data[idx] = num; 55 //更新size 56 this.size ++; 57 } 58 }
1 package cn.zcb.demo01; 2 public class MyArray { 3 private int[] data; //数组 4 private int size; //数组实际大小, 5 //容量不用写,可以由data.length()得知 6 7 //满参构造函数 8 public MyArray(int capacity){ 9 this.data = new int[capacity]; 10 this.size = 0; //开始时 实际大小size =0 11 } 12 //空参构造器 13 public MyArray(){ 14 this(10); //如果是空参的话,调用有参构造器。默认是10 15 } 16 17 //获取数组中的元素的个数 18 public int getSize(){ 19 return this.size; 20 } 21 22 //获取数组的容量 23 public int getCapacity(){ 24 return this.data.length; 25 } 26 27 //数组中是否为空 28 public boolean isEmpty(){ 29 return this.size ==0; 30 } 31 32 //向 数组的末尾添加一个新元素 33 public void addLast(int num){ 34 /* 35 if(size == this.data.length){ 36 //此时开辟的空间已经满了 37 //这里先抛出一个异常 38 throw new IllegalArgumentException("addLast failed.数组已经满了"); 39 } 40 this.data[size] = num; 41 size ++; //要维持数组 指针。 size 是当前数组中的个数。 42 */ 43 //此时其实可以直接复用 insert ()函数 44 insert(this.size,num); 45 } 46 47 //向 指定数组位置添加一个新元素 48 public void insert(int idx,int num){ 49 if(this.size == this.data.length){ 50 throw new IllegalArgumentException("数组已经放满了"); 51 } 52 if(idx <0 || idx > this.size ) 53 throw new IllegalArgumentException("索引非法"); 54 55 for(int i=this.size-1;i >= idx;--i){ 56 this.data[i+1] = this.data[i]; 57 } 58 this.data[idx] = num; 59 //更新size 60 this.size ++; 61 } 62 }
而且,给数组头添加元素也可以直接复用 给指定位置添加元素的 函数!!!
1 package cn.zcb.demo01; 2 public class MyArray { 3 private int[] data; //数组 4 private int size; //数组实际大小, 5 //容量不用写,可以由data.length()得知 6 7 //满参构造函数 8 public MyArray(int capacity){ 9 this.data = new int[capacity]; 10 this.size = 0; //开始时 实际大小size =0 11 } 12 //空参构造器 13 public MyArray(){ 14 this(10); //如果是空参的话,调用有参构造器。默认是10 15 } 16 17 //获取数组中的元素的个数 18 public int getSize(){ 19 return this.size; 20 } 21 22 //获取数组的容量 23 public int getCapacity(){ 24 return this.data.length; 25 } 26 27 //数组中是否为空 28 public boolean isEmpty(){ 29 return this.size ==0; 30 } 31 32 //向 数组的末尾添加一个新元素 33 public void addLast(int num){ 34 /* 35 if(size == this.data.length){ 36 //此时开辟的空间已经满了 37 //这里先抛出一个异常 38 throw new IllegalArgumentException("addLast failed.数组已经满了"); 39 } 40 this.data[size] = num; 41 size ++; //要维持数组 指针。 size 是当前数组中的个数。 42 */ 43 //此时其实可以直接复用 insert ()函数 44 insert(this.size,num); 45 } 46 // 向数组头添加元素 (直接复用 向指定位置添加元素的函数 ) 47 public void addFirst(int num){ 48 insert(0,num); 49 } 50 51 52 53 //向 指定数组位置添加一个新元素 54 public void insert(int idx,int num){ 55 if(this.size == this.data.length){ 56 throw new IllegalArgumentException("数组已经放满了"); 57 } 58 if(idx <0 || idx > this.size ) 59 throw new IllegalArgumentException("索引非法"); 60 61 for(int i=this.size-1;i >= idx;--i){ 62 this.data[i+1] = this.data[i]; 63 } 64 this.data[idx] = num; 65 //更新size 66 this.size ++; 67 } 68 }
在我们自己的数组中查询和修改操作:
1 package cn.zcb.demo01; 2 public class MyArray { 3 private int[] data; //数组 4 private int size; //数组实际大小, 5 //容量不用写,可以由data.length()得知 6 7 //满参构造函数 8 public MyArray(int capacity){ 9 this.data = new int[capacity]; 10 this.size = 0; //开始时 实际大小size =0 11 } 12 //空参构造器 13 public MyArray(){ 14 this(10); //如果是空参的话,调用有参构造器。默认是10 15 } 16 17 //获取数组中的元素的个数 18 public int getSize(){ 19 return this.size; 20 } 21 22 //获取数组的容量 23 public int getCapacity(){ 24 return this.data.length; 25 } 26 27 //数组中是否为空 28 public boolean isEmpty(){ 29 return this.size ==0; 30 } 31 /////////////////////增//////////////////////////// 32 //向 数组的末尾添加一个新元素 33 public void addLast(int num){ 34 /* 35 if(size == this.data.length){ 36 //此时开辟的空间已经满了 37 //这里先抛出一个异常 38 throw new IllegalArgumentException("addLast failed.数组已经满了"); 39 } 40 this.data[size] = num; 41 size ++; //要维持数组 指针。 size 是当前数组中的个数。 42 */ 43 //此时其实可以直接复用 insert ()函数 44 insert(this.size,num); 45 } 46 // 向数组头添加元素 (直接复用 向指定位置添加元素的函数 ) 47 public void addFirst(int num){ 48 insert(0,num); 49 } 50 51 //向 指定数组位置添加一个新元素 52 public void insert(int idx,int num){ 53 if(this.size == this.data.length){ 54 throw new IllegalArgumentException("数组已经放满了"); 55 } 56 if(idx <0 || idx > this.size ) 57 throw new IllegalArgumentException("索引非法"); 58 59 for(int i=this.size-1;i >= idx;--i){ 60 this.data[i+1] = this.data[i]; 61 } 62 this.data[idx] = num; 63 //更新size 64 this.size ++; 65 } 66 //////////////////////改/////////////////////////////////////// 67 //修改索引为 idx 的元素为 num 68 public void setByIndex(int idx,int num){ 69 if(idx <0 || idx > this.size) 70 throw new IllegalArgumentException("idx 错误!"); 71 72 this.data[idx] = num; 73 } 74 75 76 //////////////////////查/////////////////////////////////////// 77 //获取整个数组的概括 78 //重写 toString() 当打印arr 时候,就会调用该方法! 79 @Override 80 public String toString(){ 81 StringBuilder res = new StringBuilder(); 82 res.append(String.format("Array:size = %d,capacity = %d \n",this.size,this.data.length)); 83 res.append('['); 84 for (int i =0 ;i<this.size;i++){ 85 res.append(data[i]); 86 if(i != this.size -1) 87 res.append(", "); 88 } 89 res.append(']'); 90 return res.toString(); 91 } 92 //获取idx 索引位置的 元素 93 public int getByIndex(int idx){ 94 if (idx < 0 || idx >this.size) { 95 throw new IllegalArgumentException("索引传入错误!") 96 } 97 return this.data[idx]; 98 } 99 100 101 102 }
在我们自己的数组中 包含,搜索,和删除 操作:
1 package cn.zcb.demo01; 2 public class MyArray { 3 private int[] data; //数组 4 private int size; //数组实际大小, 5 //容量不用写,可以由data.length()得知 6 7 //满参构造函数 8 public MyArray(int capacity){ 9 this.data = new int[capacity]; 10 this.size = 0; //开始时 实际大小size =0 11 } 12 //空参构造器 13 public MyArray(){ 14 this(10); //如果是空参的话,调用有参构造器。默认是10 15 } 16 17 //获取数组中的元素的个数 18 public int getSize(){ 19 return this.size; 20 } 21 22 //获取数组的容量 23 public int getCapacity(){ 24 return this.data.length; 25 } 26 27 //数组中是否为空 28 public boolean isEmpty(){ 29 return this.size ==0; 30 } 31 /////////////////////增//////////////////////////// 32 //向 数组的末尾添加一个新元素 33 public void addLast(int num){ 34 /* 35 if(size == this.data.length){ 36 //此时开辟的空间已经满了 37 //这里先抛出一个异常 38 throw new IllegalArgumentException("addLast failed.数组已经满了"); 39 } 40 this.data[size] = num; 41 size ++; //要维持数组 指针。 size 是当前数组中的个数。 42 */ 43 //此时其实可以直接复用 insert ()函数 44 insert(this.size,num); 45 } 46 // 向数组头添加元素 (直接复用 向指定位置添加元素的函数 ) 47 public void addFirst(int num){ 48 insert(0,num); 49 } 50 51 //向 指定数组位置添加一个新元素 52 public void insert(int idx,int num){ 53 if(this.size == this.data.length){ 54 throw new IllegalArgumentException("数组已经放满了"); 55 } 56 if(idx <0 || idx > this.size ) 57 throw new IllegalArgumentException("索引非法"); 58 59 for(int i=this.size-1;i >= idx;--i){ 60 this.data[i+1] = this.data[i]; 61 } 62 this.data[idx] = num; 63 //更新size 64 this.size ++; 65 } 66 67 //////////////////////删/////////////////////////////////////// 68 //删除第一个 69 public int removeFirst(){ 70 return remove(0); //删除并将之返回出去 71 } 72 73 //删除最后一个 74 public int removeLast(){ 75 return remove(this.size-1); 76 } 77 78 //删除指定位置 的元素 79 public int remove(int idx){ //返回 删除的元素 80 if(idx < 0 || idx > this.size -1) 81 throw new IllegalArgumentException("idx错误!"); 82 int temp = this.data[idx]; 83 for (int i =idx;i<this.size - 1;i++){ 84 this.data[i] = this.data[i+1]; 85 } 86 87 this.size -- ; 88 return temp; 89 } 90 91 //删除 某个元素 不根据其位置 //它之所以返回void 是因为调用着已经知道的element ,所以没必要再返回出来了。 92 public void removeElement(int element){ 93 //首先要 寻找是否有 element 94 int idx = find(element); 95 if(idx == -1){ 96 throw new IllegalArgumentException("没有该元素"); 97 }else{ 98 remove(idx); 99 } 100 } 101 102 //////////////////////改/////////////////////////////////////// 103 //修改索引为 idx 的元素为 num 104 public void setByIndex(int idx,int num){ 105 if(idx <0 || idx > this.size) 106 throw new IllegalArgumentException("idx 错误!"); 107 108 this.data[idx] = num; 109 } 110 111 112 //////////////////////查/////////////////////////////////////// 113 //获取整个数组的概括 114 //重写 toString() 当打印arr 时候,就会调用该方法! 115 @Override 116 public String toString(){ 117 StringBuilder res = new StringBuilder(); 118 res.append(String.format("Array:size = %d,capacity = %d \n",this.size,this.data.length)); 119 res.append('['); 120 for (int i =0 ;i<this.size;i++){ 121 res.append(data[i]); 122 if(i != this.size -1) 123 res.append(", "); 124 } 125 res.append(']'); 126 return res.toString(); 127 } 128 //获取idx 索引位置的 元素 129 public int getByIndex(int idx){ 130 if (idx < 0 || idx >this.size) { 131 throw new IllegalArgumentException("索引传入错误!"); 132 } 133 return this.data[idx]; 134 } 135 136 //////////////////////包含/////////////////////////////////////// 137 public boolean contains(int num){ 138 for (int i=0;i<this.size;i++){ 139 if(this.data[i] == num){ 140 return true; 141 } 142 } 143 return false; 144 } 145 //////////////////////寻找//////////////////////////////////// 146 public int find(int num){ 147 //寻找数组中是否有 num ,如果有返回其索引,反之 返回-1 148 for (int i =0;i<this.size;i++){ 149 if(this.data[i] == num){ 150 return i; 151 } 152 } 153 return -1; 154 } 155 156 157 }
到目前为止,我们自己的数组类已经初具雏形了!
调试代码:
1 package cn.zcb.demo01; 2 3 public class Test { 4 public static void main(String[] args) { 5 MyArray arr = new MyArray(10); 6 7 //数组的容量 8 System.out.println(arr.getCapacity()); 9 10 //目前数组的大小 11 System.out.println(arr.getSize()); 12 13 //在数组末尾加一个数 14 arr.addLast(18); 15 16 //在 0 索引加入 7 17 arr.insert(0,7); 18 19 System.out.println(arr.getSize()); 20 21 //查看数组内容 会调用重写之后的toString() 22 System.out.println(arr); 23 24 //在数组的头部 加-10 25 arr.addFirst(-10); 26 System.out.println(arr); 27 28 System.out.println(arr.contains(7)); 29 System.out.println(arr.contains(101)); 30 31 //删除指定位置的元素 32 int res = arr.remove(0); //删除索引为0 的元素 33 System.out.println(res); 34 System.out.println(arr); //再次打印 arr 35 36 37 } 38 }
改善我们自己的数组之---使用泛型:
目前我们自己写的数组类最大的问题就是它只能存放int 数据类型,这肯定是不行的。
1 package cn.zcb.demo01; 2 3 public class MyArray<T> { 4 private T[] data; //数组 5 private int size; //数组实际大小, 6 //容量不用写,可以由data.length()得知 7 8 //满参构造函数 9 public MyArray(int capacity){ 10 // this.data = new int[capacity]; 11 // this.data = new T[capacity]; //不支持这样 12 this.data = (T[]) new Object[capacity]; //先new 出个 Object[] 类的,然后转为 T[] 13 this.size = 0; //开始时 实际大小size =0 14 } 15 //空参构造器 16 public MyArray(){ 17 this(10); //如果是空参的话,调用有参构造器。默认是10 18 } 19 20 //获取数组中的元素的个数 21 public int getSize(){ 22 return this.size; 23 } 24 25 //获取数组的容量 26 public int getCapacity(){ 27 return this.data.length; 28 } 29 30 //数组中是否为空 31 public boolean isEmpty(){ 32 return this.size ==0; 33 } 34 /////////////////////增//////////////////////////// 35 //向 数组的末尾添加一个新元素 36 public void addLast(T num){ 37 /* 38 if(size == this.data.length){ 39 //此时开辟的空间已经满了 40 //这里先抛出一个异常 41 throw new IllegalArgumentException("addLast failed.数组已经满了"); 42 } 43 this.data[size] = num; 44 size ++; //要维持数组 指针。 size 是当前数组中的个数。 45 */ 46 //此时其实可以直接复用 insert ()函数 47 insert(this.size,num); 48 } 49 // 向数组头添加元素 (直接复用 向指定位置添加元素的函数 ) 50 public void addFirst(T num){ 51 insert(0,num); 52 } 53 54 //向 指定数组位置添加一个新元素 55 public void insert(int idx,T num){ 56 if(this.size == this.data.length){ 57 throw new IllegalArgumentException("数组已经放满了"); 58 } 59 if(idx <0 || idx > this.size ) 60 throw new IllegalArgumentException("索引非法"); 61 62 for(int i=this.size-1;i >= idx;--i){ 63 this.data[i+1] = this.data[i]; 64 } 65 this.data[idx] = num; 66 //更新size 67 this.size ++; 68 } 69 70 //////////////////////删/////////////////////////////////////// 71 //删除第一个 72 public T removeFirst(){ 73 return remove(0); //删除并将之返回出去 74 } 75 76 //删除最后一个 77 public T removeLast(){ 78 return remove(this.size-1); 79 } 80 81 //删除指定位置 的元素 82 public T remove(int idx){ //返回 删除的元素 83 if(idx < 0 || idx > this.size -1) 84 throw new IllegalArgumentException("idx错误!"); 85 T temp = this.data[idx]; 86 for (int i =idx;i<this.size - 1;i++){ 87 this.data[i] = this.data[i+1]; 88 } 89 90 this.size -- ; 91 return temp; 92 } 93 94 //删除 某个元素 不根据其位置 //它之所以返回void 是因为调用着已经知道的element ,所以没必要再返回出来了。 95 public void removeElement(T element){ 96 //首先要 寻找是否有 element 97 int idx = find(element); 98 if(idx == -1){ 99 throw new IllegalArgumentException("没有该元素"); 100 }else{ 101 remove(idx); 102 } 103 } 104 105 //////////////////////改/////////////////////////////////////// 106 //修改索引为 idx 的元素为 num 107 public void setByIndex(int idx,T num){ 108 if(idx <0 || idx > this.size) 109 throw new IllegalArgumentException("idx 错误!"); 110 111 this.data[idx] = num; 112 } 113 114 115 //////////////////////查/////////////////////////////////////// 116 //获取整个数组的概括 117 //重写 toString() 当打印arr 时候,就会调用该方法! 118 @Override 119 public String toString(){ 120 StringBuilder res = new StringBuilder(); 121 res.append(String.format("Array:size = %d,capacity = %d \n",this.size,this.data.length)); 122 res.append('['); 123 for (int i =0 ;i<this.size;i++){ 124 res.append(data[i]); 125 if(i != this.size -1) 126 res.append(", "); 127 } 128 res.append(']'); 129 return res.toString(); 130 } 131 //获取idx 索引位置的 元素 132 public T getByIndex(int idx){ 133 if (idx < 0 || idx >this.size) { 134 throw new IllegalArgumentException("索引传入错误!"); 135 } 136 return this.data[idx]; 137 } 138 139 //////////////////////包含/////////////////////////////////////// 140 public boolean contains(T num){ 141 for (int i=0;i<this.size;i++){ 142 if(this.data[i] == num){ 143 return true; 144 } 145 } 146 return false; 147 } 148 //////////////////////寻找//////////////////////////////////// 149 public int find(T num){ 150 //寻找数组中是否有 num ,如果有返回其索引,反之 返回-1 151 for (int i =0;i<this.size;i++){ 152 if(this.data[i] == num){ 153 return i; 154 } 155 } 156 return -1; 157 } 158 159 }
1 package cn.zcb.demo01; 2 3 public class Person { 4 5 private String name; 6 private int age; 7 8 public Person(String name,int age){ 9 this.name = name; 10 this.age = age; 11 } 12 public Person(){ 13 this("张三",18); //默认赋值 张三 18 14 } 15 16 17 }
1 package cn.zcb.demo01; 2 3 public class Test { 4 5 6 public static void main(String[] args) { 7 MyArray<Integer> arrInt = new MyArray<Integer>(11); 8 arrInt.addLast(10); 9 arrInt.addLast(11); 10 arrInt.addLast(12); 11 System.out.println(arrInt); 12 13 MyArray<Character> arrChar = new MyArray<Character>(11); 14 arrChar.addLast('1'); 15 arrChar.addLast('a'); 16 arrChar.addLast('b'); 17 arrChar.addLast('c'); 18 System.out.println(arrChar); 19 20 //自定义类型 Person 21 Person p1 = new Person("tom",18); 22 Person p2 = new Person("egon",20); 23 Person p3 = new Person("alex",30); 24 25 MyArray<Person> arrPerson = new MyArray<>(); // <> 中的类型是可以省略的。 26 arrPerson.addLast(p1); 27 arrPerson.addLast(p2); 28 arrPerson.addLast(p3); 29 System.out.println(arrPerson); 30 } 31 } 32 /* 输出结果 33 Array:size = 3,capacity = 11 34 [10, 11, 12] 35 Array:size = 4,capacity = 11 36 [1, a, b, c] 37 Array:size = 3,capacity = 10 38 [cn.zcb.demo01.Person@17a7cec2, cn.zcb.demo01.Person@65b3120a, cn.zcb.demo01.Person@6f539caf] 39 * */