ArrayList 源码分析
2012-11-03 13:10
363 查看
在我们刚学Java时老师一定会说ArrayList是很好用的变长数组,你只要尽管插入删除就可以了,比C++的数组控制简单多了,
ArrayList是典型的自增长数组。
private int size; //数组中实际元素的数量
capacity表示数组的总大小,比如arr = new int[5],则capacity=5.
//initialCapacity为初始的数组大小,因为自增长数组的缺点就是重新分配数组时会耗费内存,
重新分配就意味着原空间的垃圾生成加重垃圾回收的负担,
因此如果一开始分配的大一点,以后就会避免重新分配的次数
比如你如果要插入200个元素,则:
(1)一开始就分配200个元素的capacity,则一次分配
(2)一开始分配1个,不够了再多分配1个,如果没有垃圾回收,则1+2+3+......200=20100个空间
200和20100,差别很大吧。
先回顾下ArrayList中最核心的两个语句:
int[]newarr = Arrays.copyOf(int[]old,int newlength);
//newarr = Arrays.copyOf(oldarr,newlength);
//表示将oldarr的全部内容复制到newarr中,newarr的长度为newlength
System.arraycopy(oldarr, oldbegin, newarr, newbegin,length);
//将oldarr中的第oldbegin开始,长度为length的子数组复制到newarr的从newbegin开始的位置处。
比如oldarr={1,2,3}. newarr={5,6,7},oldbegin=1,newbegin=1,length=2.则执行后,结果为newarr为{5,2,3}.
比如oldarr={1,2,3,4}. newarr={5,6,7},oldbegin=1,newbegin=1,length=3.则执行后,结果为ArrayOutofBoundsException,因为newarr长度不够
//如果当前capacity<minCapacity,则将数组的capacity增长到minCapacity
添加元素
添加多个元素
移除元素
ArrayList是典型的自增长数组。
private int size; //数组中实际元素的数量
capacity表示数组的总大小,比如arr = new int[5],则capacity=5.
//initialCapacity为初始的数组大小,因为自增长数组的缺点就是重新分配数组时会耗费内存,
重新分配就意味着原空间的垃圾生成加重垃圾回收的负担,
因此如果一开始分配的大一点,以后就会避免重新分配的次数
比如你如果要插入200个元素,则:
(1)一开始就分配200个元素的capacity,则一次分配
(2)一开始分配1个,不够了再多分配1个,如果没有垃圾回收,则1+2+3+......200=20100个空间
200和20100,差别很大吧。
先回顾下ArrayList中最核心的两个语句:
int[]newarr = Arrays.copyOf(int[]old,int newlength);
//newarr = Arrays.copyOf(oldarr,newlength);
//表示将oldarr的全部内容复制到newarr中,newarr的长度为newlength
System.arraycopy(oldarr, oldbegin, newarr, newbegin,length);
//将oldarr中的第oldbegin开始,长度为length的子数组复制到newarr的从newbegin开始的位置处。
比如oldarr={1,2,3}. newarr={5,6,7},oldbegin=1,newbegin=1,length=2.则执行后,结果为newarr为{5,2,3}.
比如oldarr={1,2,3,4}. newarr={5,6,7},oldbegin=1,newbegin=1,length=3.则执行后,结果为ArrayOutofBoundsException,因为newarr长度不够
public ArrayList(int initialCapacity) { if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; }
//默认开始分配的大小10 public ArrayList() { this(10); }
//如果当前capacity<minCapacity,则将数组的capacity增长到minCapacity
public void ensureCapacity(int minCapacity) { int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3) / 2 + 1; //newlength = (oldlength*3)/2+1 if (newCapacity < minCapacity) newCapacity = minCapacity; elementData = Arrays.copyOf(elementData, newCapacity); //此语句是自增长数组的核心语句 } }
添加元素
public boolean add(E e) { ensureCapacity(size + 1); //将size+1,如果capacity不够,则重新分配 elementData[size++] = e; return true; }
添加多个元素
public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; //新插入的元素大小 ensureCapacity(size + numNew); //插入元素钱首先判断容量够不够 System.arraycopy(a, 0, elementData, size, numNew); //将a[0,...a,length-1] 放到 elementData[size,....size+numNew-1]中去 size += numNew; return numNew != 0; }
移除元素
public E remove(int index) { RangeCheck(index); //看index是否在数组的界里 E oldValue = (E) elementData[index]; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index + 1, elementData, index,numMoved); elementData[--size] = null; //使得垃圾回收器将其回收 return oldValue; }
相关文章推荐
- util.ArrayList之源码分析
- ArrayList源码详细解析分析
- ArrayList之ConcurrentModificationException异常源码分析
- ArrayList 源码分析
- ArrayList源码分析
- java集合框架03——ArrayList和源码分析
- java源码分析之ArrayList
- 顺序线性表 ---- ArrayList 源码解析及实现原理分析
- JDK源码分析(1)-java.util.ArrayList
- java源码分析之ArrayList
- Java concurrent Framework并发容器之CopyOnWriteArrayList(1.6)源码分析
- java基础解析系列(十)---ArrayList和LinkedList源码及使用分析
- <原创> JAVA ArrayList源码分析(基于JDK7)
- ArrayList和LinkedList源码分析
- java源码分析之ArrayList
- Java集合源码学习笔记(二)ArrayList分析
- 【Java入门提高篇】Day21 Java容器类详解(四)ArrayList源码分析
- Java源码分析-ArrayList
- CopyOnWriteArrayList源码分析
- Java中ArrayList源码分析