arrayList结构的实现是数组结构,数组没有扩容机制,arrayList的扩容机制采用的是复制数组,了解你会发现ArrayList虽然实现比较简单,但是设计还是很巧妙的。咱们先来简单实现下..
咱们看下定义的全局变量
1.默认初始化空间为10,也就是默认数组空间大小
2.定义个空元素
3.顶一个数组存储元素
4.数组长度
5.构造方法默认给个空元素
// 默认初始化空间private static final int DEFAULT_CAPACITY = 10;// 空元素private static final Object[] DEFAULTCAPACITY_EMPTY_ELMENTDATA = {};// ArrayList元素数组缓冲区transient Object[] elementData;// List 集合元素数量private int size;public ArrayList() {// 默认给个空的元素,当开始添加元素的时候在初始化长度this.elementData = DEFAULTCAPACITY_EMPTY_ELMENTDATA;}
添加就是将数据存储到上边定义的elementData数组里,需要按数组下标一个个的排好存储,但是如果超出了默认的数组长度10怎么办?需要新开辟空间,把原数组原封不动的放回原有的位置,接下来看下代码。
第一次添加元素时
1.1 size为0,minCapacity得到的就是1,因为数据都是空,所以minCapacity设置了默认值10
1.2 10-0 肯定大于0,创建数组空间,那么当数组存储10条时这个minCapacity就是11,11-10大于0,需要扩容了还是运用了一个操作,这块设计的就很好
1.3 当需要扩容时找到旧数组的长度,然后用旧数组的长度+旧数组长度除以2,也就是除了第一次扩容是10,第二次就是15。
1.4 新要开辟的数字小于之前的minCapacity,newCapacity - minCapacity,那就把minCapacity赋值给newCapacity,在第一次存储数据就是这样,newCapacity=0,minCapacity=10,就需要赋值
1.5 通过Arrays.copyof(数组,长度); 开辟空间,扩容也是如此
1.6 然后存储数据,返回成功
第二次添加元素时
minCapacity=2,判断扩容2-10是小于0的,不扩容,直接存储返回数据
// 添加public boolean add(E e) {int minCapacity = size + 1;if (elementData == DEFAULTCAPACITY_EMPTY_ELMENTDATA) {minCapacity = DEFAULT_CAPACITY;}// 判断是否数组容量不足if (minCapacity - elementData.length > 0) {int oldCapacity = elementData.length;// 加原来数组长度+将原来数组长度除2int newCapacity = oldCapacity + (oldCapacity >> 1);// 扩展数据比原最小容量小就直接赋值minCapacityif (newCapacity - minCapacity < 0) {newCapacity = minCapacity;}// 进行复制原数组操作elementData = Arrays.copyOf(elementData, newCapacity);}// 存储数据elementData[size++] = e;return true;}
获取元素非常简单,根据下标获取元素即可
// 根据索引查询public E get(int index) {return (E) elementData[index];}
删除元素需要考虑移动元素的情况,假如1-2-3-4,删除2以后数组就是134,3的下标就是1,而不是以前的2。
根据System.arraycopy进行解决移动数据问题,假如现有1-2-3-5-8数据,删除了3也就是小标2的数据,那么原数组的拷贝需要从index+1开始,也就是不拷贝3的元素,拷贝到目标元素还是elementData,从index位置也就是3的位置开始拷贝,拷贝几个数据呢,需要拷贝size-index-1,也就是说5-2-1=2,拷贝两个就是5和8到elementData,这样数组最后就剩1-2-5-8,其实就是挤出去的,是不是设计很巧妙,拷贝完后将长度减1,并把数组最后一个元素置为空
public E remove(int index) {E e = get(index);// 总共拷贝多条数据int numMoved = size - index - 1;if (numMoved > 0) {// 把elementData元素进行拷贝,从index+1(就是当前要删除的下一个元素开始)// 拷贝到elementData元素,从index下标为止,赋值后所有的数据System.arraycopy(elementData, index + 1, elementData, index, numMoved);}elementData[--size] = null;return e;}
更新则和获取一样,通过下标元素找到值直接赋当前值
// 更新public boolean set(int index, E e) {elementData[index] = e;return true;}
全部代码
package linkedList;import java.util.Arrays;
import java.util.List;/*** @Author df* @Date 2022/11/20 15:16* @Version 1.0*/
public class ArrayList {// 默认初始化空间private static final int DEFAULT_CAPACITY = 10;// 空元素private static final Object[] DEFAULTCAPACITY_EMPTY_ELMENTDATA = {};// ArrayList元素数组缓冲区transient Object[] elementData;// List 集合元素数量private int size;public ArrayList() {// 默认给个空的元素,当开始添加元素的时候在初始化长度this.elementData = DEFAULTCAPACITY_EMPTY_ELMENTDATA;}// 添加public boolean add(E e) {int minCapacity = size + 1;if (elementData == DEFAULTCAPACITY_EMPTY_ELMENTDATA) {minCapacity = DEFAULT_CAPACITY;}// 判断是否数组容量不足if (minCapacity - elementData.length > 0) {int oldCapacity = elementData.length;// 加原来数组长度+将原来数组长度除2int newCapacity = oldCapacity + (oldCapacity >> 1);// 扩展数据比原最小容量小就直接赋值minCapacityif (newCapacity - minCapacity < 0) {newCapacity = minCapacity;}// 进行复制原数组操作elementData = Arrays.copyOf(elementData, newCapacity);}// 存储数据elementData[size++] = e;return true;}// 根据索引查询public E get(int index) {return (E) elementData[index];}public E remove(int index) {E e = get(index);// 总共拷贝多条数据int numMoved = size - index - 1;if (numMoved > 0) {// 把elementData元素进行拷贝,从index+1(就是当前要删除的下一个元素开始)// 拷贝到elementData元素,从index下标为止,赋值后所有的数据System.arraycopy(elementData, index + 1, elementData, index, numMoved);}elementData[--size] = null;return e;}// 更新public boolean set(int index, E e) {elementData[index] = e;return true;}public void print() {for (Object o : elementData) {System.out.print("-" + o);}System.out.println("");}public static void main(String[] args) {List list = new java.util.ArrayList();list.add("1111");System.out.println("插入元素----");ArrayList arrayList = new ArrayList();arrayList.add("1");arrayList.add("2");arrayList.add("3");arrayList.add("5");arrayList.add("8");arrayList.print();System.out.println("获取元素----");System.out.println(arrayList.get(2));System.out.println("删除元素----");arrayList.remove(2);arrayList.print();System.out.println("更新元素----");arrayList.set(2, "3");arrayList.print();}
}
执行结果

上一篇:照样子,写词语大大方方