zoukankan      html  css  js  c++  java
  • 【转】ArrayList其实就那么一回事儿之源码浅析

    转自:http://www.cnblogs.com/dongying/p/4013271.html?utm_source=tuicool&utm_medium=referral

    ArrayList 算是常用的集合之一了,不知作为javaner的你有没在百忙之中抽出一点时间看看ArrayList的源码呢。 如果看了,你会觉得其实ArrayList其实就那么一回事儿,对吧,下面就看看ArrayList的部分源码吧。

    public class ArrayList<E> extends AbstractList<E>
            implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    {
        private static final long serialVersionUID = 8683452581122892189L;
    
        //设置arrayList默认容量
        private static final int DEFAULT_CAPACITY = 10;
    
        //空数组,当调用无参数构造函数的时候默认给个空数组
        private static final Object[] EMPTY_ELEMENTDATA = {};
    
        //这才是真正保存数据的数组
        private transient Object[] elementData;
    
        //arrayList的实际元素数量
        private int size;
    
        //构造方法传入默认的capacity 设置默认数组大小
        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;
        }
    
        //构造方法传入一个Collection, 则将Collection里面的值copy到arrayList
        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);
        }
        
        //下面主要看看ArrayList 是如何将数组进行动态扩充实现add 和 remove
        
    
        public boolean add(E e) {
            ensureCapacityInternal(size + 1);  // Increments modCount!!
            elementData[size++] = e;
            return true;
        }
    
        
        public void add(int index, E element) {
            rangeCheckForAdd(index);
    
            ensureCapacityInternal(size + 1);  // Increments modCount!!
            System.arraycopy(elementData, index, elementData, index + 1,
                             size - index);
            elementData[index] = element;
            size++;
        }
        
        private void ensureCapacityInternal(int minCapacity) {
            if (elementData == EMPTY_ELEMENTDATA) {
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }
    
            ensureExplicitCapacity(minCapacity);
        }
        
        private void ensureExplicitCapacity(int minCapacity) {
            modCount++;
    
            //超出了数组可容纳的长度,需要进行动态扩展
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
        
        //这才是动态扩展的精髓,看到这个方法,ArrayList瞬间被打回原形
        private void grow(int minCapacity) {
            int oldCapacity = elementData.length;
            //设置新数组的容量扩展为原来数组的1.5倍
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            //再判断一下新数组的容量够不够,够了就直接使用这个长度创建新数组, 
            //不够就将数组长度设置为需要的长度
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
            //判断有没超过最大限制
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);
            //将原来数组的值copy新数组中去, ArrayList的引用指向新数组
            //这儿会新创建数组,如果数据量很大,重复的创建的数组,那么还是会影响效率,
            //因此鼓励在合适的时候通过构造方法指定默认的capaticy大小
            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;
        }
        
    
    }

    其实, ArrayList 的本质就是数组, ArrayList就是对数组进行动态的扩展,其add, get , remove 等等操作就是对数组的操作。至此,你还需要去记书籍上面所描述的ArrayList的特性了嘛? 如果还要记,那就弱爆了! ArrayList的一些特性都来源于数组:有序、元素可重复、插入慢、 索引快 等等一系列神马所谓的属性, 你懂了么?有木有恍然大悟的感觉

  • 相关阅读:
    POJ 1330 Nearest Common Ancestors(LCA Tarjan算法)
    LCA 最近公共祖先 (模板)
    线段树,最大值查询位置
    带权并查集
    转负二进制
    UVA 11437 Triangle Fun
    UVA 11488 Hyper Prefix Sets (字典树)
    UVALive 3295 Counting Triangles
    POJ 2752 Seek the Name, Seek the Fame (KMP)
    UVA 11584 Partitioning by Palindromes (字符串区间dp)
  • 原文地址:https://www.cnblogs.com/gmq-sh/p/5123630.html
Copyright © 2011-2022 走看看