JDK1.7——ArrayList扩容机制
2017-11-28 20:00
477 查看
ArrayList概述:
ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长。ArrayList不是线程安全的,只能用在单线程环境下。
实现了Serializable接口,因此它支持序列化,能够通过序列化传输;
实现了RandomAccess接口,支持快速随机访问,实际上就是通过下标序号进行快速访问;
实现了Cloneable接口,能被克隆。
ArrayList的构造方法:
private transient Object[] elementData; private static final Object[] EMPTY_ELEMENTDATA = {}; private static final int DEFAULT_CAPACITY = 10;//默认长度是10 public ArrayList() { super(); this.elementData = EMPTY_ELEMENTDATA; } public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; } public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); size = elementData.length; // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); }
确保内部容量:
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; //在java.lang.Integer类中常量MIN_VALUE、MAX_VALUE如下: public static final int MIN_VALUE = 0x80000000;//整型取值区间下界:-2147483648 public static final int MAX_VALUE = 0x7fffffff;//整型取值区间上界:2147483647 //在java.util.AbstractList中modCount定义如下: protected transient int modCount = 0; public boolean add(E e) { //确保内部容量(通过判断,如果够则不进行操作;容量不够就扩容来确保内部容量) ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { if (elementData == EMPTY_ELEMENTDATA) {//第一次运行将最小容量设置为10 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } private void ensureExplicitCapacity(int minCapacity) { modCount++;//存在以AbstractList中,用于存放结构改变的次数。 // 当插入元素位置大于数组最大容量,则扩容。 if (minCapacity - elementData.length > 0) grow(minCapacity); }
ArrayList的具体实现代码(部分,但已经能说明原理):
package test; import java.util.AbstractList; import java.util.Arrays; import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.RandomAccess; public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { private static final Object[] EMPTY_ELEMENTDATA = {}; private transient Object[] elementData; private int size; private static final int DEFAULT_CAPACITY = 10; private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; } public ArrayList() { super(); this.elementData = EMPTY_ELEMENTDATA; } public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); size = elementData.length; // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { if (elementData == EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } public String toString() { Iterator<E> it = iterator(); if (! it.hasNext()) return "[]"; StringBuilder sb = new StringBuilder(); sb.append('['); for (;;) { E e = it.next(); sb.append(e == this ? "(this Collection)" : e); if (! it.hasNext()) return sb.append(']').toString(); sb.append(','); } } private class Itr implements Iterator<E> { int cursor = 0; int lastRet = -1; int expectedModCount = modCount; public boolean hasNext() { return cursor != size(); } public E next() { checkForComodification(); try { int i = cursor; E next = get(i); lastRet = i; cursor = i + 1; return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); if (lastRet < cursor) cursor--; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } @Override public E get(int index) { rangeCheck(index); return elementData(index); } private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+size; } @SuppressWarnings("unchecked") E elementData(int index) { return (E) elementData[index]; } @Override public int size() { return size; } }
相关文章推荐
- java源码解读之ArrayList------jdk 1.7
- ArrayList和Vector的扩容机制
- java jdk1.7版本的ArrayList原理解析
- ArrayList的扩容机制
- ArrayList和Vector的扩容机制
- ArrayList 源码解析 及其扩展(jdk1.7)
- Java ArrayList的自动扩容机制
- ArrayList,HashMap,LinkedList 初始化大小和 扩容机制
- 集合详解(二)----ArrayList源代码剖析(JDK1.7)
- jdk1.6 1.7 list扩容的区别
- 关于ArrayList扩容机制
- StringBuffer、ArrayList、HashMap的初始容量、已经如何扩充的总结(适用范围:JDK1.7)
- ArrayList的扩容机制
- JDK容器学习之CopyOnWriteArrayList:线程安全保障机制
- 浅谈java1.8ArrayList源码(扩容机制,快速失败机制)
- ArrayList动态扩容机制--源码解析
- 使用ArrayList时代码内部发生了什么(jdk1.7)?
- java源码分析(1)---------ArrayList的扩容机制
- ArrayList扩容机制
- Java 线程池机制分析 jdk1.7