java源码分析(1)---------ArrayList的扩容机制
2017-05-15 17:51
721 查看
package source; import java.util.AbstractList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.RandomAccess; public class ArrayListNyx<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { private static final long serialVersionUID = 2024755979807710831L; private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; private transient Object[] elementData; private int size; public ArrayListNyx(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity); this.elementData = new Object[initialCapacity]; } public ArrayListNyx() { this(10); } public ArrayListNyx(Collection<? extends E> c) { elementData = c.toArray(); size = elementData.length; // c.toArray might (incorrectly) not return Object[] (see 6260652) // 有可能返回的数组类型发生改变,不是Object类型,这里是返回对应的类型 if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } public boolean isEmpty() { return size == 0; } public boolean add(E e){ ensureCapacityInternal(size+1); elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { modCount++; if(minCapacity>elementData.length){ grow(minCapacity); } } private void grow(int minCapacity) { int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; //如果创建的数据大小大于MAX_ARRAY_SIZE则使用Integer.MAX_VALUE否则使用MAX_ARRAY_SIZE if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); 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 boolean contains(Object o) { return indexOf(o) >= 0; } public int indexOf(Object o) { if (o == null) { // 如果查询为null,那么找到第一个数据中的null值,返回位置 for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { // 匹配找到的第一个数据 for (int i = 0; i < size; i++) if (o.equals(elementData[i])) return i; } return -1; } public Object[] toArray() { return Arrays.copyOf(elementData, size); } public void clear() { modCount++; // Let gc do its work for (int i = 0; i < size; i++) elementData[i] = null; size = 0; } private void fastRemove(int index) { //modCount记录ArrayList结构变化次数 modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // Let gc do its work } public boolean remove(Object o) { if(o==null){ for (int index = 0; index < size; index++) { if(elementData[index] == null){ fastRemove(index); return true; } } }else{ for (int index = 0; index < size; index++) { if(o.equals(elementData[index])){ fastRemove(index); return true; } } } return false; } public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size+numNew); System.arraycopy(a, 0, elementData, size, numNew); size = size+numNew; return numNew!=0; } public boolean removeAll(Collection<?> c) { return batchRemove(c, false); } public boolean retainAll(Collection<?> c) { return batchRemove(c, true); } public boolean batchRemove(Collection<?> c,boolean complement){ Object[] elementData = this.elementData; int r = 0, w = 0; boolean modified = false; try { for (; r < size; r++) if (c.contains(elementData[r]) == complement) elementData[w++] = elementData[r]; } finally { // Preserve behavioral compatibility with AbstractCollection, // even if c.contains() throws. if (r != size) { System.arraycopy(elementData, r, elementData, w, size - r); w += size - r; } if (w != size) { for (int i = w; i < size; i++) elementData[i] = null; modCount += size - w; size = w; modified = true; } } return modified; } @Override public E get(int index) { return null; } @Override public int size() { return size; } }
从源码上看ArrayList的底层存储来自于数组,Object[] element = new Object[10];其初始化长度为10,它的扩容机制是当前长度的二进制右移一位加上当前的长度。
(相当于*1.5)
10的二进制:1010-------------------------右移一位------------------------>101(机位数字5,为原数字的一半)========>第一次扩容大小为15
源码详见:
private void grow(int minCapacity) { int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; //如果创建的数据大小大于MAX_ARRAY_SIZE则使用Integer.MAX_VALUE否则使用MAX_ARRAY_SIZE if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); }
相关文章推荐
- java源码分析 arraylist 增长机制
- 浅谈java1.8ArrayList源码(扩容机制,快速失败机制)
- java中Arraylist源码分析扩容过程和性能优化
- [Java集合源码阅读]-ArrayList扩容机制
- ArrayList源码分析(fail-fast机制和扩容)
- 从源码分析java集合【ArrayList】
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- Java concurrent Framework并发容器之CopyOnWriteArrayList(1.6)源码分析
- JDK源码分析之java.util.ArrayList
- java非并发容器ArrayList 和 LinkedList 优缺点比较及其实现源码分析
- (7) java源码分析------之ArrayList (对应数据结构中线性表中的顺序表,JDK1.6)
- Java源码分析之ArrayList
- java源码分析之ArrayList
- Java源码分析 – ArrayList动态数组列表源码分析
- Java ArrayList源码分析
- Java集合之ArrayList源码分析
- 容器第三课,JDK源码分析,自己实现ArrayList数组扩容
- Java 回调机制及其Spring 中HibernateTemplate的源码分析
- Java NIO——Selector机制源码分析---转
- java 集合ArrayList及LinkList源码分析