实现代码
package com.itmayiedu.pattern.day01;
/**
* @author Administrator
*/
public class Array<E> {
/**
* 未查找到指定元素
*/
private final int NOT_FOUND = -1;
/**
* 数组有效元素初始个数
*/
private final int INIT_SIZE = 0;
/**
* 默认初始化容量
*/
private final static int INIT_CAPACITY = 10;
/**
* 扩容的倍数
*/
private final int DILATATION_SIZE = 2;
/**
* 存放数据的数组
*/
private E[] data;
/**
* 数组中元素个数
*/
private int size;
/**
* 有参构造函数,初始化数组容积
*
* @param capacity
*/
public Array(int capacity) {
this.data = (E[]) new Object[capacity];
this.size = INIT_SIZE;
}
/**
* 无参构造函数调用有参构造函数,初始化数组容积
*/
public Array() {
this(INIT_CAPACITY);
}
/**
* 判断数组是否为空
*
* @return false or true
*/
public boolean isEmpty() {
return size == INIT_SIZE;
}
/**
* 获取数组中元素个数
*
* @return 数组中元素个数
*/
public int getSize() {
return size;
}
/**
* 获取数组的容积
*
* @return 数组的容积
*/
public int getCapacity() {
return data.length;
}
/**
* 指定索引位置上添加元素
* (1)校验索引的合理性
* (2)指定索引位置上右边所有元素向后移动一位(最后一个元素开始向右移动,直到索引位置上停止)
* (3)有效元素个数(size)等于数组容积的时候(capacity),触发扩容
*
* @param index 索引
* @param e 添加的元素
*/
public void add(int index, E e) {
// 校验数组的合法性
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed. Require index >= 0 and index <= size");
}
// 数组有效元素个数等于数组容积时,触发扩容机制(动态数组),默认扩容是原来的2倍
if (size == getCapacity()) {
resize(2 * getCapacity());
}
// 从最后一位元素开始到指定索引位置上(包括指定索引),所有元素依次向右移动一位(前一位元素的值赋值给后一位元素)
for (int i = size - 1; i >= index; i--) {
data[i + 1] = data[i];
}
// 替换指定索引上元素
data[index] = e;
// 有效元素个数+1
size++;
}
/**
* 数组中向最后一位插入元素
*
* @param e 元素
*/
public void addLast(E e) {
add(size, e);
}
/**
* 向数组中第一位插入元素
*
* @param e 元素
*/
public void addFirst(E e) {
add(0, e);
}
/**
* 获取index索引位置的元素
*
* @param index 索引
* @return 元素
*/
public E get(int index) {
// 校验数组的合法性
if (index < 0 || index > size) {
throw new IllegalArgumentException("Get failed. Require index >= 0 and index <= size");
}
return data[index];
}
/**
* 修改index索引位置的元素为e
*
* @param index 索引
* @param e 需要修改的元素
*/
public void set(int index, E e) {
// 校验数组的合法性
if (index < 0 || index > size) {
throw new IllegalArgumentException("Set failed. Require index >= 0 and index <= size");
}
data[index] = e;
}
/**
* 查找数组中是否有元素e
*
* @param e 元素
* @return false or true
*/
public boolean contains(E 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(E e) {
for (int i = 0; i < size; i++) {
if (data[i].equals(e)) {
return i;
}
}
return NOT_FOUND;
}
/**
* 从数组中删除index位置的元素, 返回删除的元素
* (1)校验索引的合理性
* (2)指定索引位置上右边所有元素向左移动一位(从索引位置上的下一个元素开始,直到最后一个元素)
* (3)移动以后赋值,有效元素个数减1,最后1位被赋值为空,防止内存泄漏
* (4)有效元素个数(size)等于数组容积的1/2时候(capacity),触发缩容
*
* @param index 索引
* @return 删除的元素
*/
public E remove(int index) {
// 校验数组的合法性
if (index < 0 || index > size) {
throw new IllegalArgumentException("Remove failed. Require index >= 0 and index <= size");
}
E ret = data[index];
// 当前索引位置上的下一位开始到最后一位一次向左移一位
for (int i = index + 1; i < size; i++) {
data[i - 1] = data[i];
}
// 有效元素个数-1
size--;
// 最后1位赋值为空,防止内存泄漏
data[size] = null;
// 数组有效元素个数等于数组容积1/2时,触发缩容机制(动态数组),默认缩容是原来的1/2倍
if (size == getCapacity() / DILATATION_SIZE) {
resize(getCapacity() / DILATATION_SIZE);
}
return ret;
}
/**
* 从数组中删除第一个元素, 返回删除的元素
*
* @return 删除的元素
*/
public E removeFirst() {
return remove(0);
}
/**
* 从数组中删除最后一个元素, 返回删除的元素
*
* @return 删除的元素
*/
public E removeLast() {
return remove(size - 1);
}
/**
* 删除指定的元素
*
* @param e 删除的元素
*/
public void removeElement(E e) {
int index = find(e);
if (index != NOT_FOUND) {
remove(index);
}
}
/**
* 数组扩容,数组拷贝有四种方法(我们选用效率最高的本地方法)
*
* @param capacity 数组的容大小
*/
private void resize(int capacity) {
E[] newData = (E[]) new Object[capacity];
System.arraycopy(data, 0, newData, 0, size);
data = newData;
}
@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();
}
}
1.添加分析
/**
* 指定索引位置上添加元素
* (1)有效元素个数(size)等于数组容积的时候(capacity),触发扩容
* (2)指定索引位置上右边所有元素向后移动一位(最后一个元素开始向右移动,直到索引位置上停止)
* (3)校验索引的合理性
*
* @param index 索引
* @param e 添加的元素
*/
public void add(int index, E e) {
// 校验数组的合法性
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed. Require index >= 0 and index <= size");
}
// 数组有效元素个数等于数组容积时,触发扩容机制(动态数组),默认扩容是原来的2倍
if (size == getCapacity()) {
resize(2 * getCapacity());
}
// 从最后一位元素开始到指定索引位置上(包括指定索引),所有元素依次向右移动一位(前一位元素的值赋值给后一位元素)
for (int i = size - 1; i >= index; i--) {
data[i + 1] = data[i];
}
// 替换指定索引上元素
data[index] = e;
// 有效元素个数+1
size++;
}
2.删除操作分析
/**
* 从数组中删除index位置的元素, 返回删除的元素
* (1)校验索引的合理性
* (2)指定索引位置上右边所有元素向左移动一位(从索引位置上的下一个元素开始,直到最后一个元素)
* (3)移动以后赋值,有效元素个数减1,最后1位被赋值为空,防止内存泄漏
* (4)有效元素个数(size)等于数组容积的1/2时候(capacity),触发缩容
*
* @param index 索引
* @return 删除的元素
*/
public E remove(int index) {
// 校验数组的合法性
if (index < 0 || index > size) {
throw new IllegalArgumentException("Remove failed. Require index >= 0 and index <= size");
}
E ret = data[index];
// 当前索引位置上的下一位开始到最后一位一次向左移一位
for (int i = index + 1; i < size; i++) {
data[i - 1] = data[i];
}
// 有效元素个数-1
size--;
// 最后1位赋值为空,防止内存泄漏
data[size] = null;
// 数组有效元素个数等于数组容积1/2时,触发缩容机制(动态数组),默认缩容是原来的1/2倍
if (size == getCapacity() / DILATATION_SIZE) {
resize(getCapacity() / DILATATION_SIZE);
}
return ret;
}