关于ArrayList源码
发布时间:2020-12-15 07:46:16 所属栏目:Java 来源:网络整理
导读:一、构造方法 1 private static final int DEFAULT_CAPACITY = 10; 2 3 //空参的构造方法,初始化数组长度为默认值,默认值为10 4 public ArrayList() { 5 this .elementData =DEFAULTCAPACITY_EMPTY_ELEMENTDATA; 6 } //有参的构建函数 2 public ArrayList(
一、构造方法1 private static final int DEFAULT_CAPACITY = 10; 2 3 //空参的构造方法,初始化数组长度为默认值,默认值为10 4 public ArrayList() { 5 this.elementData =DEFAULTCAPACITY_EMPTY_ELEMENTDATA; 6 } //有参的构建函数 2 public ArrayList(int initialCapacity) { 3 if (initialCapacity > 0) { 4 this.elementData = new Object[initialCapacity]; 5 } else { 6 if (initialCapacity != 0) { 7 throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity); 8 } 9 10 this.elementData = EMPTY_ELEMENTDATA; 11 } 12 13 } 有参的构建函数:
二、add()方法public boolean add(E e) { 2 //检测是否需要扩容 3 下1ensureCapacityInternal(minCapacity:size + 1); // size+1是当前存的数据个数 4 //数组赋值 5 6 elementData[size++] = e; 7 return true; 8 } void ensureCapacityInternal(int minCapacity) { 2 //判断数值是否是空的,空就取默认值和当前存储个数中最大的 3 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { 4 minCapacity = Math.max(DEFAULT_CAPACITY,minCapacity); 5 } 6 7 ensureExplicitCapacity(minCapacity); 8 } 9 //判断是否需要扩容,如果传入的个数大于默认容量10的话,扩容 void ensureExplicitCapacity( 3 modCount++;//如果确定要扩容,会修改modCount 4 // overflow-conscious code 6 if (minCapacity - elementData.length > 0) 7 grow(minCapacity); 8 } //需要扩容的话,默认扩容一半 void grow( 4 int oldCapacity = elementData.length;//赋值为初始数组的数据 int newCapacity = oldCapacity + (oldCapacity >> 1);//默认扩容一半 if (newCapacity - minCapacity < 0)//如果还不够 ,那么就用 能容纳的最小的数量。(add后的容量) 7 newCapacity = minCapacity; 8 if (newCapacity - MAX_ARRAY_SIZE > 0) 9 newCapacity = hugeCapacity(minCapacity); 10 // minCapacity is usually close to size,so this is a win: 11 elementData = Arrays.copyOf(elementData,newCapacity);//拷贝,扩容,构建一个新数组, 12 } 13 指定插入索引位置:void add(int index,E element) { 2 rangeCheckForAdd(index);//越界判断 如果越界抛异常 3 4 ensureCapacityInternal(size + 1); // Increments modCount!! 5 System.arraycopy(elementData,index,elementData,index + 1, 6 size - index); //向后移动一位 7 elementData[index] = element; 8 size++; 9 } 10 关于arraycopy(Object var0,int var1,Object var2,int var3,int var4)
void rangeCheckForAdd(int index){ if(index>size || index<0) new IndexOutofBoundsException(outofBoundsMsg(index)); 三、remove()方法public E remove(int index) { 2 检测当前下标是否越界 3 下1rangeCheck(index); 5 modCount++; 6 E oldValue = elementData(index); 7 将index+1及之后的元素向前移动一位,覆盖被删除的值 8 int numMoved = size - index - 1; 9 if (numMoved > 0) 10 下下2System.arraycopy(elementData,index+1,128);"> 11 numMoved); 12 将最后一个位置的元素清空 13 14 elementData[--size] = null; 15 16 return oldValue; 17 } boolean remove(Object o) { if (o == null) { 3 for (int index = 0; index < size; index++) 4 if (elementData[index] == 5 下1fastRemove(index); 6 true;} //从0开始遍历,大小为数组长度,找到后直接删除 7 } 8 9 if (o.equals(elementData[index])) { 10 fastRemove(index); 11 12 } 13 } 14 如果没有匹配元素,返回false 15 false; 16 } 不需要判断是是因为是按内容匹配,找不到内容就不处理 四、一个报错案例1 1ist.add(10); 2 1ist.add(11); 3 1ist.add(12); 4 1ist.add(13); 5 1ist.add(15); 6 for(Integer num:1ist){ 7 if(num==12){ 8 1ist.remove(num); 9 } 10 }I 11 //报错 12 //Exception in thread"main"java.util.concurrentModificationException 14 void checkForComodification){ 16 if(modcount != expectedModcount) 17 new ConcurrentModificationException(); 18 } 为什么会报错?进行移除操作后并没有更新modcount,所以内容才会不匹配 //使用迭代器遍历删除 2 Iterator<Integet > it=list.iterator(); while(it.next){ 4 Integer num=it.next(); if(num==12){ 6 it.remove(); 7 } 8 } 因为迭代器内部有一个expectedModcount=modcount, (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |