所谓的动态数组:意味着数组可以根据存放元素的数量,动态的调节数组的长度;
package dataStructure.chapter1;
/**
* 自定义数组
* @Author: zjtMeng
* @Date: 2019/12/15 12:46
* @Version 1.0
*/
public class Array<E> {
private E[] data;
private int size;
/**
* 有参构造函数
* @param capacity
*/
public Array(int capacity){
data = (E[]) new Object[capacity];
}
/**
* 默认构造函数
*/
public Array(){
this(10);
}
/**
* 获取数组中元素的个数
* @return
*/
public int getSize(){
return size;
}
/**
* 获取数组的容量
* @return
*/
public int getCapacity(){
return data.length;
}
/**
* 返回数组是否为空
* @return
*/
public boolean isEmpty(){
return size == 0;
}
/**
* 在所有元素之后添加一个新元素
*/
public void addLast(E e){
add(size,e);
}
/**
* 在所有元素之前添加一个新元素
* @param e
*/
public void addFirst(E e){
add(0,e);
}
/**
* 在index位置上插入元素e
* @param index
* @param e
*/
public void add(int index,E e){
//判断传入的插入位置参数是否规范以及合乎要求,
if (index <0 || index> size)
throw new IllegalArgumentException("add failed. Require index >=0 || index < size");
//判断当前数组是否已经达到容量了
if (size == data.length)
resize(2 * data.length);
//从插入位置开始,后面的所有元素全部向后挪一位
for (int i=size-1; i>=index; i--)
data[i+1] = data[i];
data[index] = e;
size++;
}
/**
* 返回数组
* @return
*/
@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();
}
/**
* 返回指定索引位置的元素
* @param index
* @return
*/
public E get(int index){
//判断传入的插入位置参数是否规范以及合乎要求,
if (index <0 || index> size)
throw new IllegalArgumentException("get failed. Require index >=0 || index < size");
return data[index];
}
/**
* 修改指定索引位置上的元素
* @param index
* @param e
*/
public void set(int index,E e){
if (index <0 || index> size)
throw new IllegalArgumentException("set failed. Require index >=0 || index < size");
data[index] = e;
}
/**
* 判断数组是否存在某元素e
* @param e
* @return
*/
public boolean contains(int e){
for (int i = 0; i < size; i++) {
if (data[i] .equals(e))
return true;
}
return false;
}
/**
* 查找数组中第一个元素e所在的缩影,如果不存在元素e,则返回-1
* @param e
* @return
*/
public int find(int e){
for (int i = 0; i < size; i++) {
if (data[i] .equals(e))
return i;
}
return -1;
}
/**
* 从数组中删除指定位置的元素,并返回删除的元素
* @param index
* @return
*/
public E remove(int index){
//判断传入的插入位置参数是否规范以及合乎要求,
if (index <0 || index> size)
throw new IllegalArgumentException("add failed. Require index >=0 || index < size");
E ret = data[index];
for (int i = index+1; i < size ; i++) {
data[i-1] = data[i];
}
size--;
//loitering object != memory leak
data[size] = null;
//当数组元素减少到一定程度时,数组容量缩小一倍;
//此处1/4的目的是防止出现复杂度震荡,避免出现数组频繁的进行扩容和缩容极端情况发生
if (size == data.length/4 && data.length/2 !=0)
resize(data.length/2);
return ret;
}
/**
* 删除数组的第一个元素,返回删除的元素
* @return
*/
public E removeFirst(){
return remove(0);
}
/**
* 删除数组最后一个元素,返回删除的元素
* @return
*/
public E removeLast(){
return remove(size-1);
}
/**
* 从数组中删除所有元素e
* @param e
*/
public void removeAllElement(int e){
while(find(e) != -1){
int index = find(e);
remove(index);
}
}
/**
* 扩容
* @param newCapacity
*/
private void resize(int newCapacity){
E[] newData = (E[]) new Object[newCapacity];
for (int i=0; i<size; i++){
newData[i] = data[i];
}
data = newData;
}
}