1、MyList 接口
/**
* 用于 MyArrayList 继承
*
* @param <E>
*/
public interface MyList<E> {
/**
* 添加一个元素
*
* @param element : 元素
* @return : 返回是否插入成功 boolean
*/
public boolean add(E element);
/**
* 指定位置添加元素
*
* @param index : 要添加的元素位置
* @param element : 元素
*/
public void add(int index, E element);
/**
* 获取指定索引位置的元素
*
* @param index : 要获取的元素位置
* @return : 返回获取的元素
*/
public E get(int index);
/**
* 替换指定索引位置的元素
*
* @param index : 要替换的元素位置
* @param element : 要替换的元素
* @return : 返回旧的元素
*/
public E set(int index, E element);
/**
* 移除指定索引位置的元素
*
* @param index : 要移除的元素位置
* @return : 返回被移除的元素
*/
public E remove(int index);
/**
* 获取 MyArrayList 大小, 即 index + 1
*
* @return
*/
public int size();
/**
* 清空数组
*/
public void clear();
}
2、MyArrayList 实现类
public class MyArrayList<E> implements MyList<E> {
/**
* 0.0 ArrayList 底层采用数组存放
*/
private E[] elementData;
/**
* 0.1 ArrayList 的大小(它包含的元素数),
* 也可表示为下一个元素插入位置(即: index+1)
*/
private int size;
/**
* 0.2 默认 Object[] 数组容量
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 0.3 初始化 默认初始化容量
*/
public MyArrayList() {
elementData = (E[]) new Object[DEFAULT_CAPACITY];
}
/**
* 0.3 初始化 默认初始化容量
*
* @param initialCapacity : 容量大小 int 类型
*/
public MyArrayList(int initialCapacity) {
if (initialCapacity < 0) {
// 抛出 非法参数异常
throw new IllegalArgumentException();
}
// 初始化数组容量为 initialCapacity
elementData = (E[]) new Object[initialCapacity];
}
/**
* 1.0 判断 index 是否合法
*
* @param index : 要处理的索引值
*/
private void rangCheck(int index) {
// 判断 index 是否合法
if (index < 0 || index >= size) {
// 抛出 数组下标越界异常.
throw new IndexOutOfBoundsException();
}
}
/**
* 1.0 判断 add() 方法的 index 是否合法
*
* @param index : 要处理的索引值
*/
private void rangCheckForAdd(int index) {
// 判断 index 是否合法
if (index < 0 || index > size) {
// 抛出 数组下标越界异常.
throw new IndexOutOfBoundsException();
}
}
/**
* 2.0 确认容量进行扩容
*/
private void ensureCapacity() {
//① “下一个插入元素的索引值size” 比 数组长度小, 无需扩容
if (size < elementData.length) {
return;
}
//② 新的容量 = 旧容量 * 1.5
int newCapacity = elementData.length + (elementData.length >> 1);// *1.5(扩容1.5倍)
//③ 生成一个新的数组
E[] newElements = (E[]) new Object[newCapacity];
//④ 复制到新的数组
for (int i = 0; i < size; i++) {
newElements[i] = elementData[i];
}
//⑤ 将 elements 指向新的数组.
elementData = newElements;
}
/**
* 0.00 添加一个元素
*
* @param element : 元素
* @return : 返回是否插入成功 boolean
*/
@Override
public boolean add(E element) {
//2.01 扩容
// 结合 “0.00 在某个位置添加某个元素” ,修改 1.01 代码
add(size, element);
//1.01 在元素数组elementData的 index = size 的位置插入该object元素
// 并且在插入完成后 size++ , 即: 为元素数组保存一个空元素的索引elementData[size] = null .
/* 代码1.01: */
// elementData[size++] = object;
return true;
}
/**
* 0.00 在某个位置添加某个元素
*
* @param index : 要添加的元素位置
* @param element : 元素
*/
@Override
public void add(int index, E element) {
//1.03 判断 index 是否合法
rangCheckForAdd(index);
//2.01 扩容
ensureCapacity();
//1.02 先将 elementData[index] 后的所有 object 向后移动一位, 将 elementData[index] 的位置空出来,
// 再将 elementData[index] = object.
// ①先将 i 的初始值赋为 size, 即: 当前 elementData 元素数组中 ”空(null)元素“ 索引值
// ②再判断要插入的 index 位置是否比 i 小
// ③如果满足②条件, 执行 elementData[i] = elementData[i-1]; 将元素后移一位
// ④for循环: 直到 i = index+1 , 此时 elementData[index] 位置为 null.
for (int i = size; i > index; i--) {
elementData[i] = elementData[i - 1];
}
// ⑤将④处理后的 elementData[index] = object;
elementData[index] = element;
size++;// ⑥为下一个要添加的元素保留位置
}
/**
* 0.00 查找某个位置的元素
*
* @param index : 要获取的元素位置
* @return : 返回获取的元素
*/
@Override
public E get(int index) {
//① 判断 index 是否合法
rangCheck(index);
//② 返回对应 index 位置对应的元素
return elementData[index];
}
/**
* 0.00 覆盖某个位置的元素
*
* @param index : 要替换的元素位置
* @param element : 要替换的元素
* @return : 返回被覆盖的元素
*/
@Override
public E set(int index, E element) {
//① 判断 index 是否合法
rangCheck(index);
//② 获取被覆盖的元素
E oldValue = elementData[index];
//③ 覆盖 index 位置的元素
elementData[index] = element;
//⑤ 返回被覆盖的元素
return oldValue;
}
/**
* 0.00 移除指定位置的元素
*
* @param index : 要移除的元素位置
* @return : 返回要移除的元素
*/
@Override
public E remove(int index) {
//① 判断 index 是否合法
rangCheck(index);
//② 获取要移除的元素
E oldValue = elementData[index];
//③ 将要移除的元素之后的元素向前移动一位
for (int i = index; i < size; i++) {
elementData[i] = elementData[i + 1];
}
//④ 下一个元素插入位置索引值减 1
//size--;
//⑤ ”下一个元素插入位置“ = null
//elementData[size] = null;
//⑥ 对 ④、⑤ 步进行简化
elementData[--size] = null;
//⑥ 返回要移除的元素
return oldValue;
}
/**
* 0.00 返回数组大小
*
* @return
*/
@Override
public int size() {
return size;
}
/**
* 0.00 清空数组
*/
@Override
public void clear() {
//① 循环清空数组中所有元素
for (int i = 0; i < size; i++) {
elementData[i] = null;
}
//② 将数组大小置为 0
size = 0;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer("Size = " + size + ", Data = ").append("[");
for (int i = 0; i < size; i++) {
sb.append(elementData[i] + ", ");
if (i == size - 1) {
sb.append(elementData[i]);
}
}
sb.append("]");
return sb.toString();
}
}
3、Student 测试实体类
public class Student {
private int id;
private String name;
private String address;
public Student(int id, String name, String address) {
this.id = id;
this.name = name;
this.address = address;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
@Override
protected void finalize() {
System.out.println("This desctory!");
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", Address='" + address + '\'' +
'}';
}
}
4、测试类
public class Test {
public static void main(String[] args) {
MyArrayList arrayList = new MyArrayList();
arrayList.add(new Student(1, "梨花1", "龙门大厦1"));
arrayList.add(new Student(2, "梨花2", "龙门大厦2"));
arrayList.add(new Student(3, "梨花3", "龙门大厦3"));
arrayList.add(new Student(4, "梨花4", "龙门大厦4"));
arrayList.add(new Student(1, "梨花1", "龙门大厦1"));
arrayList.add(new Student(2, "梨花2", "龙门大厦2"));
arrayList.add(new Student(3, "梨花3", "龙门大厦3"));
arrayList.add(new Student(4, "梨花4", "龙门大厦4"));
arrayList.add(new Student(1, "梨花1", "龙门大厦1"));
arrayList.add(new Student(2, "梨花2", "龙门大厦2"));
arrayList.add(new Student(3, "梨花3", "龙门大厦3"));
arrayList.add(new Student(4, "梨花4", "龙门大厦4"));
System.out.println("添加 " + arrayList);
arrayList.add(4, new Student(8, "梨花8", "龙门大厦8"));
System.out.println("插入 " + arrayList);
System.out.println("添加一个元素 " + arrayList.add(new Student(10, "梨花4", "龙门大厦4")));
System.out.println("添加一个元素 " + arrayList);
System.out.println("获取元素" + arrayList.get(4));
System.out.println("覆盖元素 " + arrayList.set(4, new Student(888, "梨花8", "龙门大厦8")));
System.out.println("覆盖元素 " + arrayList);
System.out.println("移除元素 " + arrayList.remove(4));
System.out.println("移除元素 " + arrayList);
System.out.println("元素数量 " + arrayList.size());
arrayList.clear();
System.out.println("清空数组 " + arrayList);
// 告诉虚拟机进行垃圾回收
System.gc();
System.out.println(arrayList);
}
}