java集合之ArrayList(1)

java容器接口类图

注:Map接口没有继承自Collection接口,因为Map表示的是关联式容器而不是集合。但Java为我们提供了从Map转换到Collection的方法,可以方便的将Map切换到集合视图。
上图中提供了Queue接口,却没有Stack,这是因为Stack的功能已被JDK 1.6引入的Deque取代。

接口实现

  implementations
Hash Table Resizable Array balanced tree Linked List Hash Table + Linked List
interface set  HashSet   TreeSet   LinkedHashSet
list   ArrayList   LinkedList  
deque(双向队列)   ArrayDeque   LinkedDeque  
map  HashMap   TreeMap   LinkedHashMap

 ArratList介绍

 arrayList实现了List接口,底层实现采用了数组,是顺序容器(存的顺序和取出来的顺序是一致的),该容器未实现同步(即线程不安全的容器),这点和vector不同。。每个ArrayList都有一个容量(capacity)默认情况为10,表示底层数组的实际大小,容器内存储元素的个数不能多于当前容量。当向容器中添加元素时,如果容量不足,容器会自动增大底层数组的大小。前面已经提过,Java泛型只是编译器提供的语法糖,所以这里的数组是一个Object数组,以便能够容纳任何类型的对象。

方法剖析

size(), isEmpty(), get(), set()方法均能在常数时间内完成,add()方法的时间开销跟插入位置有关,addAll()方法的时间开销跟添加元素的个数成正比。

主要说明下add()和addAll()方法

由于在新增元素时,ArrayList的容量(capacity)可能不够,所以会涉及到动态扩容

1.扩容时机

首先来看add方法

public boolean add(E e){
    ensureCapacityInternal(size + 1);
    elementData[size++] = e;
    return true;
}
View Code

可以看到,检验容器容量的函数ensureCapacityInternal的入参是size+1

private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_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);
    }
View Code

可以看到,获取的是size+1的长度和capacity中的最大值,如果minCapacity>当前容器数据的长度,则扩容(即如果容器capacity=10,当插入第九个元素的时候就会扩容,而不是等到第10个元素)

一下是扩容的实现代码(扩容后的长度为之前的1.5倍),扩容后将原数组的值复制到扩容的的数组中,之前的数组等待垃圾回收释放。

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);
    }
View Code

 

posted @ 2018-11-27 17:05  楠木(鱼摆摆)  阅读(256)  评论(0)    收藏  举报