ArrayList简单实现API
ArrayList简单介绍
ArrayList底层是使用动态数组生成的,若在创建ArrayList集合时,未指定其容量,则在添加元素时,会进行扩容处理,第一次会将空的集合扩容为10,后面若添加元素仍然超过其最大容量,则将其每次都扩容为原来长度的1.5倍;
下面自定义完成集合ArrayList的创建,其中包含简单的API:
- 空参构造方法
- 添加元素的方法: add(E e)
- 获取集合长度的方法: getSize()
- 根据集合的索引获取元素的方法: get(int index)
- 根据集合的索引修改元素的方法: set(int index)
- 根据集合的索引删除指定元素的方法: remove(int index)
- 集合的toString()方法
代码实现
package com.bingym.arraylist.myarraylist;
public class MyArrayList<E> {
//自定义ArrayList集合;简单实现基本的api:
//1.add(E e) 2.remove(int index) 3.get(int index) 4.set(int index,E element) 5.getSize() 6.toString()
//定义数组,用来存储集合的元素
private Object[] elementData;
//定义变量,用来记录数组的个数
private int size;
//定义空数组,用来在创建集合对象的时候给elementData初始化
private Object[] emptyArray = {};
//定义常量,用来记录集合的常量
private final int DEFAULT_CAPACITY = 10;
//构造方法
public MyArrayList() {
//给elementData初始化
elementData = emptyArray;
}
//定义add方法
public boolean add(E e) {
//调用之前需要判断是否需要进行扩容
grow();
//将元素添加到集合:即elementData数组中
elementData[size++] = e;
return true;
}
//定义简单扩容的方法
private void grow() {
//判断集合存储元素的数组是否等于emptyArray
if (elementData == emptyArray) {
//此时集合为空集合{}
//则第一次扩容:将其长度置为10
elementData = new Object[DEFAULT_CAPACITY];
}
//如果不是空集合,即进行当前集合长度的1.5倍进行扩容处理
if (size == elementData.length) {
//当前元素的个数已经等于当前集合的长度
//先定义变量记录集合的老容量
int oldCapacity = elementData.length;
//进行扩容处理
int newCapacity = oldCapacity + (oldCapacity >> 1);//右移1位等价于oldCapacity/2
//创建一个新的长度的数组
Object[] obj = new Object[newCapacity];
//然后将老数组的元素拷贝放新数组中
//从elementData拷贝到obj中
System.arraycopy(elementData,0,obj,0,elementData.length);
elementData = obj;
}
}
//校验索引是否越界的方法
private void checkIndex(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("索引越界");
}
}
//获取集合的长度
public int getSize() {
return size;
}
//根据索引获取元素
public E get(int index) {
//调用checkIndex方法校验索引是否越界
checkIndex(index);
//直接从集合的数组中获取元素并返回
return (E) elementData[index];
}
//修改集合元素内容的方法
public E set(int index,E element) {
//checkIndex方法校验索引是否越界
checkIndex(index);
//把当前修改的index的元素取出来
E value = (E) elementData[index];
//替换元素
elementData[index] = element;
//将老元素内容返回
return value;
}
//根据索引删除当前元素的方法
public E remove(int index) {
//校验索引
checkIndex(index);
//取出当前索引的值
E value = (E) elementData[index];
//计算需要移动的个数
int numMoved = size - index - 1;
//判断移动的个数是否大于0
if (numMoved > 0) {
System.arraycopy(elementData,index+1,elementData,index,numMoved);
}
//将最后一个位置元素置为null,尽快被垃圾回收机制回收
elementData[--size] = null;
return value;//返回要删除的元素
}
//toString方法
public String toString() {
//对集合进行判断:若为空,返回"[]"
if (size == 0) {
return "[]";
}
//不为空,创建StringBuilder进行集合元素的拼接
StringBuilder sb = new StringBuilder();
sb.append("[");
//循环遍历数组
for (int i = 0; i < size; i++) {
if (i == size-1) {
//到达集合的最后一个元素
sb.append(elementData[i]).append("]");
}else {
sb.append(elementData[i]).append(",").append(" ");
}
}
//将sb转换成字符窗进行返回
return sb.toString();
}
}
自定义集合测试
package com.bingym.arraylist.myarraylist;
import org.junit.Test;
public class TestMyArrayList {
@Test
public void test() {
MyArrayList<String> list = new MyArrayList<>();
//测试add
list.add("feng");
list.add("bin");
list.add("gym");
list.add("xxx");
//测试set
list.set(3,"lsl");
//测试get
String str = list.get(3);
System.out.println(str);
//测试remove
String removeStr = list.remove(3);
System.out.println("要删除的元素是:" + removeStr);
//测试toString
System.out.println(list.toString());
}
}
输出结果:
lsl
要删除的元素是:lsl
[feng, bin, gym]