Java总结 - List实现类ArrayList&LinkedList (3)

经过后面再次实验, 除了首次使用ArrayList的add方法会加载一些东西,当我们再次new出ArrayList的时候,首次使用add方法就不会再家在任何东西了,如下的测试代码

List<String> list = new ArrayList<>(); list.add("X"); List<String> list2 = new ArrayList<>(); list2.add("X");

其中在我debug时候会看到很多getLoader`loders一些方法或者属性,那么在这感觉是首次使用ArrayList的类加载机制在起作用,我在社区提问题了,所以大家可以看一下,联想到类加载机制非常感谢回复我的1382148494135822`大哥, 问答页 : 

回到add方法上来,我们发现它会调用类中的另一个add方法.源码如下

private void add(E e, Object[] elementData, int s) { //如果满了就扩容 if (s == elementData.length) elementData = grow(); //然后将要存的元素存入到数组指定位置 elementData[s] = e; //加一 size = s + 1; }

这个方法中用到的grow方法源码如下

private Object[] grow() { return grow(size + 1); } private Object[] grow(int minCapacity) { return elementData = Arrays.copyOf(elementData, newCapacity(minCapacity)); } //返回至少与给定最小容量相同的容量 private int newCapacity(int minCapacity) { int oldCapacity = elementData.length; //10+(10>>1)=15 ,即扩容1.5倍 int newCapacity = oldCapacity + (oldCapacity >> 1); //扩容后如果还比最小的容量小或者相等的话 if (newCapacity - minCapacity <= 0) { //判断是否是初始化的情况 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) //是的话就直接返回默认容量10,从这就可以看出来才刚开始初始化大小 return Math.max(DEFAULT_CAPACITY, minCapacity); if (minCapacity < 0) // overflow错误,最小值不可能是负数 throw new OutOfMemoryError(); //如果不是初始化也不是参数错误,那么就返回最小的容量 return minCapacity; } //到这表示扩容后的容量比最小容量要大 //是否达到了最大长度,如果没到达就返回扩容后的长度,否则就调用hugeCapacity return (newCapacity - MAX_ARRAY_SIZE <= 0) ? newCapacity : hugeCapacity(minCapacity); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow错误 throw new OutOfMemoryError(); //如果达到了规定的最大数组长度,那么就扩容到整数的最大长度,否则就是当前默认的数组最大长度 return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

还有一个指定位置的add方法,下面是源码实现

public void add(int index, E element) { //检查是否数组越界 rangeCheckForAdd(index); modCount++; final int s; //临时保存size Object[] elementData; //临时保存elementData if ((s = size) == (elementData = this.elementData).length) elementData = grow(); //如果长度等于size代表要扩容了 //核心方法System.arraycopy,他会将你要操作的index地方的位置空出了 System.arraycopy(elementData, index, elementData, index + 1, s - index); //然后index空出来的位置赋值 elementData[index] = element; //加一 size = s + 1; }

好了ArrayList的add方法已经介绍完了,如果有不对的地方请指正

addAll

源码实现

public boolean addAll(Collection<? extends E> c) { //转换数组 Object[] a = c.toArray(); modCount++; //获取传入集合的长度 int numNew = a.length; //是空集合的话直接返回 if (numNew == 0) return false; Object[] elementData; final int s; //如果传入集合的长度大于elementData中空余的位置个数就增长 if (numNew > (elementData = this.elementData).length - (s = size)) elementData = grow(s + numNew); //增长完了就将传入的数据copy进去 System.arraycopy(a, 0, elementData, s, numNew); //元素个数修改 size = s + numNew; //返回成功 return true; }

Get

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwsjsd.html