JAVA集合框架之下ArrayList与Vector

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012364631/article/details/78783682

Vector和ArrayList是一对,都是可变大小的线性表,用数组实现,区别是Vector是线程安全的。他们都直接继承自AbstractList抽象类

ArrayList

特点:

这里写图片描述
实现了List接口的所有方法(废话,而且也实现了AbstractList抽象类的所有方法,谁叫他是个具体类呢),允许包含null
在添加元素的时候,可以动态调整容量,(也可以手动调整)
所以建议在添加一大堆数据前手动调用ensureCapacity(int)方法,来减少动态扩展空间的次数
这里写图片描述

我们还记的AbstractList抽象类已经实现了大多数List接口的方法(依赖于iterator实现的),而在ArrayList中又把这些方法重写了一遍,这次不依赖iterator了,通过index实现,比如:
这里写图片描述
注:clear方法并不是通过直接使size=0来达到清空数组的目的,而是吧每个位置都设置为null,这要gc就有可能进行回收工作

又比如:
这里写图片描述
这里写图片描述
所以ArrayList实现了RandomAccess标记接口,标记自己的能力,建议别人通过index访问我。

Fail-fast机制

Java提供了一种fail-fast机制来避免多线程访问时可能出现问题
这里写图片描述
http://www.jb51.net/article/84468.htm
当在使用迭代器的时候,迭代器发现同时有人修改了数组(修改的手段不包括调用迭代器自己的remove add方法),迭代器就会抛出异常。
那么迭代器是如何发现同时有人了数组呢?
迭代器通过比较expectedModCount和modCount,如果不相等,说明有人修改了数组。因为expectedModCount在迭代器初始化时被赋值为当时的modCount,这个赋值只进行一次,而如果有人修改数组(比如调用 list.add()),就会执行modCount++
注:modCount代表数组被modify过的次数

DEFAULTCAPACITY_EMPTY_ELEMNTDATA

这里写图片描述
关于为什么要设置DEFAULTCAPACITY_EMPTY_ELEMENTDATA 数组,网上也没人能给出明确的解释,
只有一点比较明显,就是在使用无参构造方法时,会将elementData=DEFAULTCAPACITY_EMPTY_ELEMENTDATA,
而如果调用ArrayList(int size),构造方法时,如果参数为0,会将elementData=EMPTY_ELEMENTDATA,区别就是在存入第一个数据时,对扩展的大小会有影响,但是为什么这样设计就不得而知了
这里写图片描述
注意:调用无参构造方法后,elementData的容量还是0,在第一次加入元素时会变成10
这里写图片描述
如果是使用的无参构造方法,在第一次插入时调用ensureCapacityInternal(1),if之后
MinCapacity变成10,然后调用ensureExplicitCapacity(10)会将elementData的长度变为10;

如果使用ArrayList(int initialCapacity) 传入0;
在第一次插入时调用ensureCapacityInternal(1),不进入if,然后调用ensureExplicitCapacity(1)会将elementData的长度变为1;

在其他任何情景下(不是第一次插入值),ensureCapacityInternal()都不会进入if,之后的逻辑就都一样了:在ensureExplicitCapacity()中,如果确实容量不足,则将容量扩展为原先的1.5倍

ensureCapactiy

这里写图片描述

Vector

Vector 就相当于线程安全的ArrayList
注意到构造函数的一个细节(ArrayList中也存在)

 public Vector(Collection<? extends E> c) {
        elementData = c.toArray();
        elementCount = elementData.length;
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
}

http://blog.csdn.net/jdsjlzx/article/details/54344233
6260652是jdk的一个bug编号
toArray方法由子类重写后,可能返回的不是Objcet[]类型

这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/u012364631/article/details/78783682
今日推荐