ArrayList结构图
ArrayList特点
ArrayList的优点如下:
- ArrayList 底层以数组实现,是一种随机访问模式。因此查找的时候非常快。
- ArrayList 在顺序添加一个元素的时候非常方便。
ArrayList 的缺点如下:
- 删除元素的时候,需要做一次元素复制操作。如果要复制的元素很多,那么就会比较耗费性能。
- 插入元素的时候,也需要做一次元素复制操作,缺点同上。
适用场景:ArrayList 比较适合顺序添加、随机访问的场景。
Java代码实现ArrayList
注意点:注意数组下标越界问题
public class MyArrayList<E> {
// 数组长度
private int size;
// 数组已存数据的大小
private int index;
// 声明数组
private E dadaArr[];
// 构造函数完成初始化
public MyArrayList(int size){
this.size = size;
this.index = 0;
this.dadaArr = (E[]) new Object[size];
}
// 插入元素
public void add(int loc,E data){
// ArrayList需要保证数据的连续性所以插入元素需要保证loc小于等于index,否则报错
if(loc > index){
System.out.println("java.lang.IndexOutOfBoundsException");
return;
}
// 判断越界问题:已存数据大小需要小于数组长度才可以插入,否则触发扩容机制后插入
if(index ++ < size){
// 插入数据时前面的数据不动,后面的数据需要往后依次移动1
for (int i = size -1; i > loc ; i--) {
// 将loc位置后的所有元素往后移动
dadaArr[i] = dadaArr[i -1];
}
dadaArr[loc] = data;
}else{
// 否则走扩容逻辑,通过位运算进行1.5倍扩容
increaseCapacity(loc,data);
}
}
// 移除元素(这里只写了根据loc移除对应元素,其余根据数据值移除逻辑类似,自行补充)
public E remove(int loc){
// 同理需要判断是否loc越界
if(loc > index){
System.out.println("java.lang.IndexOutOfBoundsException");
return null;
}
E removeData = dadaArr[loc];
// 由于移除元素不需要考虑越界问题,所以这里直接将loc后的元素前移1
for (int i = loc; i < dadaArr.length; i++) {
// 判断是否到了最后一个位置,到了就将最后一个位置的元素置为null
if(i != dadaArr.length -1){
dadaArr[i] = dadaArr[i + 1];
}else{
dadaArr[i] = null;
}
}
// 每次移除一个元素已存数据的大小减1
index--;
return removeData;
}
// 根据loc获取元素
public E get(int loc){
return dadaArr[loc];
}
// 更新根据loc元素
public void update(int loc,E data){
dadaArr[loc] = data;
}
// 扩容方法 1.5倍扩容 (注意,其缩容逻辑类似,就不贴出)
private void increaseCapacity(int loc,E data){
int oldCapacity = dadaArr.length;
// 1 + 0.5 倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
E[] newDataArr = (E[])new Object[newCapacity];
// 将之前数组中的数据复制到扩容后的新数组中去
for (int i = 0; i < dadaArr.length; i++) {
newDataArr[i] = dadaArr[i];
}
// 扩容数据转移后再走插入数据流程,后面的数据需要往后依次移动1
for (int i = newDataArr.length - 1; i > loc ; i--) {
// 将loc位置后的所有元素往后移动
newDataArr[i] = newDataArr[i -1];
}
newDataArr[loc] = data;
// 最后将新的数组对象赋给dadaArr并且将size修改为扩容后的size
dadaArr = newDataArr;
size = newDataArr.length;
}
// 打印方法
public void print(){
System.out.println("index:" + index);
for(int i = 0 ; i < index ; i++){
System.out.print(dadaArr[i] + " ");
}
System.out.println();
}
// 测试
public static void main(String[] args) {
MyArrayList<String> myArrList = new MyArrayList<>(4);
myArrList.add(0,"a");
myArrList.add(1,"b");
myArrList.add(2,"c");
myArrList.add(3,"d");
myArrList.print();
myArrList.add(3,"f");
myArrList.add(3,"g");
String remove = myArrList.remove(3);
System.out.println("remove---->"+remove);
System.out.println(myArrList);
}
}