特点分析
源码:
构造方法
有参构造
int;给定初始容量 ;
传入集合进入:通过这个有参构造函数,
ArrayList
可以方便地根据现有的集合创建一个新的ArrayList
实例,确保新实例的初始容量足够容纳所有元素,从而提高性能。这个设计使得ArrayList
在处理集合时更加灵活和高效。
无参构造
public class ArrayList01 {
public static void main(String[] args) {
//1.调用无参构造方法是,默认初始化容量是0
List<String> names = new ArrayList<>();
//向集合中添加元素,第一次调用方法的时候,初始化长度为10;
names.add("张三");
names.add("李四");
names.add("王五");
names.add("赵六");
.
.
.
//扩容为元容量的1.5倍,创建一个新的数组,然后将之前的东西拷贝进去;
names.add("11");
//修改元素
names.set(1"李四");
//插入
names.add(2,"张三");
}
}
add()方法源码分析
add(E e, Object[] elementData, int s) 是一个私有方法,主要负责具体的添加逻辑,包括检查数组是否需要扩展和更新元素的数量。
add(E e) 是公共方法,是外部调用的入口,负责处理一些额外的操作(如修改计数器)并调用私有的添加逻辑方法。oldCapacity >> 1 右移一位,增长量为当前长度的一半。
构造方法 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; //这是个常量 } //点进DEFAULTCAPACITY_EMPTY_ELEMENTDATA,是下边代码,这是对常量的赋值,赋值为数组长度为0,空数组 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //当增添一个元素,调add()源码 public boolean add(E e) { modCount++; //记录修改的次数 add(e, elementData, size);//调用的是private方法,内部具体实现增添的逻辑 return true; } //内部逻辑 private void add(E e, Object[] elementData, int s) { if (s == elementData.length) elementData = grow(); //调用grow()方法 elementData[s] = e; size = s + 1; } private Object[] grow() { return grow(size + 1); //调用有参grow()方法 } //判断数组长度是否增加的方法 private Object[] grow(int minCapacity) { int oldCapacity = elementData.length; if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { int newCapacity = ArraysSupport.newLength(oldCapacity, minCapacity - oldCapacity, /* minimum growth */ oldCapacity >> 1 /* preferred growth */); return elementData = Arrays.copyOf(elementData, newCapacity); } else { //DEFAULT_CAPACITY = 10; 变量为10; return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)]; } }
set()方法源码分析
进入的set方法(实例方法)
//实例方法 public E set(int index, E element) { Objects.checkIndex(index, size); //判断下标是否越介 E oldValue = elementData(index); //先把对应要修改的值先取出来存好 elementData[index] = element; //修改 return oldValue; //返回修改之前的数据 }
add(index,data):指定位置插入
拷贝数组,index从哪个位置开始拷贝,index+1,从哪个位置开始放,s-index:拷贝多长 ,这是核心
public void add(int index, E element) { rangeCheckForAdd(index); //检查是否越界 modCount++; final int s; //数组长度 Object[] elementData; if ((s = size) == (elementData = this.elementData).length) //判断是否需要增长 elementData = grow(); System.arraycopy(elementData, index, elementData, index + 1, s - index); //拷贝数组,index从哪个位置开始拷贝,index+1,从哪个位置开始放,s-index:拷贝多长 elementData[index] = element; size = s + 1; }
remove(index,data)
先检查是否越界,将删除位置元素之后的拷贝产生位移,将最后一个位置置空
public E remove(int index) { Objects.checkIndex(index, size); final Object[] es = elementData; @SuppressWarnings("unchecked") E oldValue = (E) es[index]; fastRemove(es, index); return oldValue; }