简单动态数组的实现
自己建立动态数组
动态数组的数据封装在Array中自己定义的data静态数组中
首先创建一个自定义的静态数组,并且向其中添加自己想要实现的方法,如添加元素,获取容量,查找元素等
创建初始的静态数组,代码如下
public class Array { private int[] data; private int size;//不让用户随意改动 //构造函数,传入数组的容量 capability构造Array public Array(int capacity) { data = new int[capacity]; size = 0; } //提供默认构造函数,默认数组容量capability = 10 public Array() { this(15); } }
为此静态数组添加方法:
public class Array { private int[] data; private int size;//不让用户随意改动 //构造函数,传入数组的容量 capability构造Array public Array(int capacity) { data = new int[capacity]; size = 0; } //提供默认构造函数,默认数组容量capability = 10 public Array() { this(15); } //用户查询数组的元素量size public int getSize() { return size; } //获取数组的容量:length public int getCapacity() { return data.length; } //返回数组是否为空 public boolean isEempty() { return size == 0; } //向数组最开始添加元素 public void addFirst(int e) { add(0,e); } //向数组最后添加元素 public void addLast(int e) { if(size == data.length) { throw new IllegalArgumentException("addLast failed Array is full"); } //add(size,e); data[size] = e; size++; } //向指定位置添加元素,将插入索引位置后的元素向后挪 public void add(int index , int e) { if(size == data.length) { throw new IllegalArgumentException("addLast failed Array is full"); } if(index<0||index>size) {//index==size相当于在最后插入元素 throw new IllegalArgumentException("Add failed . require index>=0 and index<=size"); } for(int i = size-1;i>=index;i--) { data[i+1] = data[i]; } data[index] = e; size++; } //获取index索引位置的元素,使用如此封装的方法的好处:用户永远无法查询未使用的空间(查询元素) int get(int index) { if(index<0||index>=size) throw new IllegalArgumentException("Get failed.index is illegal"); return data[index]; } //将某个元素改变为元素e(修改元素) void set(int index,int e) { if(index<0||index>=size) throw new IllegalArgumentException("Set failed.index is illegal"); data[index] = e; } @Override public String toString() { //拼接一个字符串 StringBuilder res = new StringBuilder(); res.append(String.format("Array:size = %d,capacity = %d\n",size,data.length)); res.append("["); for(int i = 0;i<size;i++) { res.append(data[i]); if(i!=size - 1) { res.append(", "); } } res.append("]"); return res.toString();//因为是StringBuilder } //是否包含某个元素 public boolean contains(int e) { for(int i = 0;i<size;i++) {//(这里是最简单的遍历) if(data[i]==e) { return true; } } return false; } //找到元素对应的索引位置,如果不存在元素则返回-1 public int find(int e) { for(int i = 0;i<size;i++) { if(data[i]==e) { return i; } } return -1; } //删除指定位置元素(并且返回此元素)(有指定索引)元素都向左移(size--,但是用户看不到size上有值的影响 ) public int remove(int index) { if(index<0||index>=size) { throw new IllegalArgumentException("Remove failed.index is illegal"); } int ret = data[index]; for(int i = index+1 ;i<size;i++) { data[i-1] = data[i]; } size--; return ret; } //删除第一个元素,返回删除的元素 public int removeFirst() { return remove(0); } //删除最后一个元素 public int removeLast() { return remove(size-1); } //删除所有e public void removeAll(int e) { while(find(e)!=-1) { removeElement(e); } } //删除是否具有的某个元素 public void removeElement(int e) { int index = find(e); if(index!=-1) { remove(index); } } }
当前数组类的最大问题是只能适用于int变量
使用泛型:使其可以放置任意类型的数据(包括自定义的类型)
(非基本数据类型)但是基本数据类型都有对应的包装类
将数组改造成泛型数组
在resize()中
开一个更大的数组,将data数组里的数据复制进newdata
使data指向newdata
public class Array <T>{//这里的T可以换成自定义的其他名称 public Array(int capacity) { data = (T[])new Object[capacity];//强制类型转换为T[]型数组,Object类是所有类的父类 size = 0; } } --改造函数:改变部分函数返回值类型和参数类型 进一步修改为动态数组: public class Array <T>{//这里的T可以换成自定义的其他名称 private T[] data; private int size;//不让用户随意改动 //构造函数,传入数组的容量 capability构造Array public Array(int capacity) { data = (T[])new Object[capacity];//强制类型转换为T[]型数组,Object类是所有类的父类 size = 0; } //提供默认构造函数,默认数组容量capability = 10 public Array() { this(10); } //用户查询数组的元素量size public int getSize() { return size; } //获取数组的容量:length public int getCapacity() { return data.length; } //返回数组是否为空 public boolean isEempty() { return size == 0; } //向数组最开始添加元素 public void addFirst(T e) { add(0,e); } //向数组最后添加元素 public void addLast(T e) { if(size == data.length) { throw new IllegalArgumentException("addLast failed Array is full"); } //add(size,e); data[size] = e; size++; } //向指定位置添加元素,将插入索引位置后的元素向后挪 public void add(int index , T e) { if(index<0||index>size) {//index==size相当于在最后插入元素 throw new IllegalArgumentException("Add failed . require index>=0 and index<=size"); } if(size >= data.length) { resize(data.length*2);//扩容 } for(int i = size-1;i>=index;i--) { data[i+1] = data[i]; } data[index] = e; size++; } //获取index索引位置的元素,使用如此封装的方法的好处:用户永远无法查询未使用的空间(查询元素) T get(int index) { if(index<0||index>=size) throw new IllegalArgumentException("Get failed.index is illegal"); return data[index]; } //将某个元素改变为元素e(修改元素) void set(int index,T e) { if(index<0||index>=size) throw new IllegalArgumentException("Set failed.index is illegal"); data[index] = e; } @Override public String toString() { //拼接一个字符串 StringBuilder res = new StringBuilder(); res.append(String.format("Array:size = %d,capacity = %d\n",size,data.length)); res.append("["); for(int i = 0;i<size;i++) { res.append(data[i]); if(i!=size - 1) { res.append(", "); } } res.append("]"); return res.toString();//因为是StringBuilder } //是否包含某个元素 public boolean contains(T e) { for(int i = 0;i<size;i++) {//(这里是最简单的遍历) if(data[i]==e) { return true; } } return false; } //找到元素对应的索引位置,如果不存在元素则返回-1 public int find(T e) { for(int i = 0;i<size;i++) { if(data[i]==e) { return i; } } return -1; } //删除指定位置元素(并且返回此元素)(有指定索引)元素都向左移(size--,但是用户看不到size上有值的影响 ) public T remove(int index) { if(index<0||index>=size) { throw new IllegalArgumentException("Remove failed.index is illegal"); } T ret = data[index]; for(int i = index+1 ;i<size;i++) { data[i-1] = data[i]; } size--; if(size<=data.length/4&&data.length/2!=0) { resize(data.length/2); } //data[size]=null;//使java垃圾回收机制可以将此对象回收 return ret; } //删除第一个元素,返回删除的元素 public T removeFirst() { return remove(0); } //删除最后一个元素 public T removeLast() { return remove(size-1); } //删除所有e public void removeAll(T e) { while(find(e)!=-1) { removeElement(e); } } //删除是否具有的某个元素 public void removeElement(T e) { int index = find(e); if(index!=-1) { remove(index); } } private void resize(int newCapacity) { T[] newdata =(T[]) new Object[newCapacity]; for(int i = 0;i<size;i++) { newdata[i] = data[i]; } data = newdata; } }
学习的时候喜欢用Markdown做记录,存货已经堆满文件夹了

浙公网安备 33010602011771号