1.创建一个动态数组
为了实现动态数组的增删查改,我们需要将动态数组定义为类的对象,在通过成员方法来实现这些功能。
public class MyArray { // 存放元素仍然还是int[] private int[] data; // 表示当前动态数组中已经存储的元素个数 private int size; public MyArray(){ // 默认开辟10个大小的整形数组长度 this(10); } //从外部传入数组长度 public MyArray(int initCap){ this.data = new int[initCap]; }
数组的扩容,在数组增删查改的过程中难免会出现数组的数据溢出,所以我们得保证数组长度足够,就要进行数组的扩容。
// 在当前数组中添加一个新的元素val public void add(int val){ data[size] = val; size++; // 元素在添加的过程中,有可能把当前的数组占满了 // 如何知道当前data数组已满? if(size == data.length){ grow(); } }// 对于外部的使用者来说,压根不知道你MyArray这个类中还有int[],数组的扩容对外部也是不可见的 // 设置为private权限 private void grow(){ // copyOf方法返回扩容后的新数组 this.data = Arrays.copyOf(data,data.length*2); }
使用方法对数组进行打印操作。
public String toString(){ String ret = "["; // 此时取得是有效数据,使用size属性 // size表示当前有效元素的下一个索引位置 for (int i = 0; i < size; i++) { ret += data[i]; if(i != size - 1){ ret += ","; } } ret += "]"; return ret; }
数组的增加:
在当前动态数组中index位置插入值为val的元素
public void add(int index,int val){ // 先判断边界条件,index是否是一个非法的索引 // size是有效的元素个数,index == size // 插入时 index = size,就是在数组尾部插入 // index = 0,就是在数组头部插入,index = size就是在有效元素的尾部插入 if(index < 0 || index > size){ // 错误输出 System.err.println("add index illegal"); return; } // 从当前最后一个有效元素开始向后搬移元素,把index位置空出来 for (int i = size - 1; i > index; i--) { data[i + 1] = data[i]; } // index位置空出来了 data[index] = val; size++; // 判断数组是否已满 if(size == data.length){ grow(); } }
数组的查找:
查询当前动态数组中第一个值为val的元素所对应的索引,若不存在返回-1,表示val不存在
public int getByValue(int val){ for (int i = 0; i < size; i++) { if(data[i] == val){ return i; } } // 说明遍历完没有找到val元素,val不存在 return -1; }
判断当前动态数组是否包含值为val的元素
public boolean coutains(int val){ int index = getByValue(val); return index != -1; }
查询当前动态数组中索引为index的元素值
public int get(int index){ if(index < 0 || index >= size){ System.err.println("get index illegal!"); return -1; } return data[index]; }
修改:
修改index位置的元素为新的值newVal,返回修改前的值
public int set(int index,int newVal){ if(index < 0||index >= size){ System.err.println("set index illegal!"); return -1; } int oldVal = data[index]; data[index] = newVal; return oldVal; }
将动态数组中第一个值为oldVal的元素修改为newVal
public boolean setValue(int oldVal,int newVal){ int index = getByValue(oldVal); if(index != -1){ data[index] = newVal; return true; } System.err.println("old value is not exist"); return false; }
删除索引为index的元素,返回删除前的元素值。
public int removeIndex(int index){ if(index < 0||index >= size){ System.err.println("remove index illegal"); return -1; } // 进行元素搬移,从index开始,后一个元素覆盖前一个元素,一直走到size -1(最后一个有效元素) // data[i] = data[i + 1] // 最后一个元素向前搬移i + 1 == size - 1 => i < size - 1 int oldVal = data[index]; for (int i = index; i < size - 1; i++) { data[i] = data[i + 1]; } size--; return oldVal; }
删除动态数组第一个元素的值
public int removeFirst(){ return removeIndex(0); }
删除动态数组最后一个元素的值
public int removeLast(){ return removeIndex(size - 1); }
删除第一个元素为val的值,删除成功输出true,删除失败输出false。
public boolean removeByValueOnce(int val){ for (int i = 0; i < size; i++) { if(data[i] == val){ removeIndex(i); return true; } } return false; }
删除所有元素为val的值,如果删除成功返回true,如果删除失败输出false。
public boolean removeByValue(int val){ int count = 0; for (int i = 0; i < size; i++) { for (int j = i; j < size; j++) { if(data[j] == val){ removeIndex(j); count ++; } } } if(count > 0){ return true; } return false; }
总结:在增删查改时,要注意原数组的长度是否够用,否则数组溢出,导致数据丢失。一个元素val要是没有出现在数组中时,则输出索引为-1,索引只有正整数,若是看到输出索引为-1,则此元素在数组中没有找到。