在Java中创建一个数组,Java对这个数组只提供了下面的一些方法;数组一旦声明,其存储的数据类型和数组的容量大小就一定;且不提供对数组的增删改查操作,需要自己实现;
下面是对静态数组的改进,实现存储任意类型、提供增删改查操作、可扩容:
package com.itheima.array; /** * @author GuoBaoYu * 使用泛型,可以存放任意类型的数据; */ public class Array<E> { private E[] data; //内部是静态数组 private int size; public Array(int capacity) { data =(E[]) new Object[capacity]; size = 0; } /** * 默认构造一个容量为10的数组 */ public Array() { this(10); } public int getCapacity(){ return data.length; } public boolean isEmpty(){ return size==0 ; } public int getSize(){ return size; } public void addLast(E element){ add(size, element); } public void addFirst(E element){ add(0,element); } //动态数组进行自动扩容和减少容量 private void resize(int newCapacity){ E[] newData = (E[]) new Object[newCapacity]; for(int i = 0; i < size;i++){ newData[i] = data[i]; } data = newData; } /** * @param index * @param element * 向指定的位置插入元素 */ public void add(int index,E element){ if(size == getCapacity()){ // throw new IllegalArgumentException("AddLast is failed. Array is full."); // 之前如果数组空间满了,抛出异常;现在进行扩容 int newCapacity = getCapacity()*2; resize(newCapacity); } if(index < 0 || index > size){ throw new IllegalArgumentException("Argument index is illegal.index is required index >=0 and index <= size. "); } for(int i = size-1; i>=index; i--){ data[i+1] = data[i]; } data[index] = element; size++; } @Override public String toString(){ StringBuilder builder = new StringBuilder(); builder.append(String.format("size = %d,capacity = %d\t", size,getCapacity())); builder.append("["); for(int i = 0; i < size; i++){ builder.append(data[i]); if(i<size-1){ builder.append(","); } } builder.append("]"); return builder.toString(); } public E get(int index){ if(index >=size || index <0){ throw new IllegalArgumentException("Argument index is illegal."); } return data[index]; } public void set(int index, E element){ if(index >=size || index <0){ throw new IllegalArgumentException("Argument index is illegal."); } data[index] = element; } public boolean contains(E element){ for(int i =0; i <size;i++){ if(data[i].equals(element)){ return true; } } return false; } public int find(E element){ for(int i=0 ; i < size; i++){ if(data[i].equals(element)){ return i; } } return -1; } //删除index位置的元素,并返回删除的元素的值 public E remove(int index){ if(index < 0 || index >= size){ throw new IllegalArgumentException("Remove failed.index is an illegal argument."); } E element = data[index]; for(int i = index+1; i < size; i++){ data[i-1] = data[i]; } size--; //改善算法性能;进行懒缩容; if(size <= getCapacity() /4 && data.length/2 !=0){ resize(getCapacity()/2); } return element; } //删除第一个元素 public E removeFirst(){ return remove(0); } //删除最后一个元素 public E removeLast(){ return remove(size-1); } /** * @param element * @return * 删除指定的数据 */ public boolean removeElement(E element){ int find = find(element); if(find!=-1){ remove(find); return true; } return false; } }
思路:
1.使用泛型,使得可以存储任意类型的数据
2.在进行添加操作时,如果数组存储数据的个数size已经等于数组创建时声明的容量capacity,则进行自动扩容:创建一个2倍容量的新临时数组newData,将原来的数组data中的数据复制到newData中,再更改data的指向;相当于对data进行了扩容;
类似的,当数组中的数据很少时,可以自动缩容: