Java原生数组的大小在创建时就被固定,并且不能更改。这意味着它们是静态的或者说是不可变的。如果你尝试添加或删除数组中的元素,你会得到一个ArrayIndexOutOfBoundsException
异常或者ArrayStoreException
异常。
这种特性会导致我们在使用数组时不太方便,虽然ArrayList、
LinkedList
或HashSet这
些集合类提供了动态增加删除元素的功能,但是数组的访问效率比ArrayList高,所以我们如果在遇到访问较多的情景,最好还是使用数组来存储数据。
下面我们就来写一个支持增删改查的动态数组,这样就不用担心数组越界、增加删除元素不方便的一系列问题啦!
为了防止复杂度震荡,在remove方法中进行了一定的优化
public class MyArray<E> {
private E[] data;
private int size;
// 构造函数,capacity为数组的最大容量
public MyArray(int capacity) {
data = (E[]) new Object[capacity];
size = 0;
}
public MyArray() {
this(10);
}
public int getSize() {
return size;
}
public int getCapacity() {
return data.length;
}
public boolean isEmpty() {
return size == 0;
}
// 在第index位置插入一个新元素e
public void add(int index, E e) {
if (index < 0 && index > size)
throw new IllegalArgumentException("Add failed,index is illegal.");
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++;
}
private void resize(int v) {
E[] newData = (E[]) new Object[v];
for (int i = 0; i < size; i++) {
newData[i] = data[i];
}
data = newData;
}
public void addLast(E e) {
add(size, e);
}
public void addFirst(E e) {
add(0, e);
}
//获取索引为index的值
public E get(int index) {
if (index < 0 || index >= size)
throw new IllegalArgumentException("Get failed,Index is illegal.");
return data[index];
}
// 修改索引index位置的元素为e
public void set(int index, E e) {
if (index < 0 || index >= size)
throw new IllegalArgumentException("Set failed,Index is illegal.");
data[index] = e;
}
public boolean contains(E e) {
for (int i = 0; i < size; i++) {
if (data[i].equals(e))
return true;
}
return false;
}
public int find(E e) {
for (int i = 0; i < size; i++) {
if (data[i].equals(e))
return i;
}
return -1;
}
public E remove(int index) {
if (index < 0 || index >= size)
throw new IllegalArgumentException("Remonve failed,Index is illegal.");
E ret = data[index];
for (int i = index + 1; i < size; i++) {
data[i - 1] = data[i];
}
size--;
data[size] = null;
// 防止复杂度震荡
if (size == data.length / 4 && data.length / 2 != 0) {
resize(data.length / 2);
}
return ret;
}
public E removeFirst() {
return remove(0);
}
public E removeList() {
return remove(size - 1);
}
public void removeElement(E e) {
int index = find(e);
if (index != -1) {
remove(index);
}
}
@Override
public String toString() {
StringBuilder strb = new StringBuilder();
strb.append(String.format("MyArray:size=%d,capacity=%d\n", size, data.length));
strb.append("[");
for (int i = 0; i < size; i++) {
strb.append(data[i]);
if (i != size - 1)
strb.append(",");
}
strb.append("]");
return strb.toString();
}
}