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;
- // 加原来数组长度+将原来数组长度除2
- int newCapacity = oldCapacity + (oldCapacity >> 1);
- // 扩展数据比原最小容量小就直接赋值minCapacity
- if (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;
- // 加原来数组长度+将原来数组长度除2
- int newCapacity = oldCapacity + (oldCapacity >> 1);
- // 扩展数据比原最小容量小就直接赋值minCapacity
- if (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();
-
- }
- }
执行结果
