[TOC]
# 動態數組
~~~
//動態數組
public class Array<E> {
private E[] data;
//數組中有多少有效元素
private int size;
//構造函數,傳入數組的容量capacity構造Array
public Array(int capacity) {
data = (E[]) new Object[capacity];
size = 0;
}
//無參數的構造函數,默認數組的容量capacity=10
public Array() {
this(10);
}
//獲取數組中的元素個數
public int getSize() {
return size;
}
//獲取數組的容量
public int getCapacity() {
return data.length;
}
//數組是否為空
public boolean isEmpty() {
return size == 0;
}
//向數組添加一個新元素
public void addLast(E e) {
add(size, e);
}
//向數組頭部添加一個新元素
public void addFirst(E e) {
add(0, e);
}
//在第index個位置插入一個新元素e
public void add(int index, E e) {
//如果index小于0,那這是非法的.如果大于有效大小,那么中間有沒有填充的非法空間,也不允許
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed.Require index >= 0 and index <= size.");
}
//如果容量用滿了就擴容
if (size == data.length) {
//擴容2倍
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 newCapacity) {
E[] newData = (E[]) new Object[newCapacity];
for (int i = 0; i < size; i++) {
newData[i] = data[i];
}
data = newData;
}
//獲取元素
public E get(int index) {
//不讓用戶訪問哪些沒有設置的元素
if (index < 0 || index > size) {
throw new IllegalArgumentException("Get failed.Index is illegal");
}
return data[index];
}
//獲取數組中最后一個元素
public E getLast() {
return get(size -1);
//我們不寫data[size-1]的原因是,如果size是0,我們就傳遞一個-1了.get方法有保護機制
}
//獲取第一個元素
public E getFirst() {
return get(0);
}
//修改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;
}
//查看數組是否有元素e
public boolean contains(E e) {
for (int i = 0; i < size; i++) {
if (data[i].equals(e)) {
return true;
}
}
return false;
}
//查找數組中元素e所在的索引,如果不存在元素e,則返回-1
public int find(E e) {
for (int i = 0; i < size; i++) {
if (data[i].equals(e)) {
return i;
}
}
return -1;
}
//從數組中刪除index位置的元素,返回刪除的元素
public E remove(int index) {
if (index < 0 || index > size) {
throw new IllegalArgumentException("Remove failed.Index is illegal");
}
E ret = data[index];
//刪除位置的元素依次往前移動一位
for (int i = index + 1; i < size; i++) {
data[i - 1] = data[i];
}
size--;
// 原來這位置是指向一個引用的,java中指向一個引用,這個位置就不能被垃圾回收,
// 如果我們把他置為null,就會很快被垃圾回收了
// loitering objects != memory leak 游蕩對象不等于內存泄露
// 游蕩對象,在我們程序中存在,但是無法被垃圾回收處理
data[size] = null;
//如果數組中的利用少到一定的程度就把數據縮容
//創建的數組空間不能等于0
if (size == data.length / 2 && data.length / 2 != 0) {
resize(data.length / 2);
}
return ret;
}
//刪除第一個元素
public E removeFirst() {
return remove(0);
}
//刪除最后一個元素
public E removeLast() {
//不怕數組為空,因為我們把size-1傳進去了
return remove(size - 1);
}
//刪除一個元素e,因為用戶知道是那個元素了,就不返回被刪除的元素了
public void removeElement(E e) {
//數組中可以存放重復元素的,刪除了這個元素,不能保證數組中沒有這個元素了
int index = find(e);
if (index != -1) {
remove(index);
}
}
@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();
}
}
~~~
# 測試
~~~
public class TestArray {
public static void main(String[] args) {
Array<Integer> arr = new Array<Integer>();
for (int i = 0; i < 10; i++) {
arr.addLast(i);
}
System.out.println(arr);
arr.add(1, 100);
System.out.println(arr);
arr.addFirst(-1);
System.out.println(arr);
arr.remove(2);
System.out.println(arr);
arr.removeElement(4);
System.out.println(arr);
}
}
~~~