[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);
}
}
~~~