zoukankan      html  css  js  c++  java
  • JDK1.7——ArrayList扩容机制

    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;
            }
        
    }
    

      

      

  • 相关阅读:
    为ccflow增加禁用用户立刻生效功能
    关于工作流引擎授权问题的需求变更
    sql server 2005 安装过程中出现错误Insatalling performance countter: Cannot create a file when that file already exists.
    web.config中错误
    三个SQL视图查出所有SQL Server数据库字典
    恢复备份的数据库
    sql语句读取excel数据
    It is an error to use a section registered allowDefinition='MachineToApplication' beyond application level. 错误
    DOS命令实现创建文件夹
    如何查看sql server 的版本(网摘)
  • 原文地址:https://www.cnblogs.com/liqing-weikeyuan/p/7911788.html
Copyright © 2011-2022 走看看