对比Vector、ArrayList、LinkedList有何区别?

Vector

1.线程安全的动态数组

2.如果不需要线程安全,并不建议选择,毕竟同步是有额外开销的。Vector 内部是使用对象数组来保存数据,可以根据需要自动的增加容量,当数组已满时,会创建新的数组,并拷贝原有数组数据。

3.扩容大小默认为0,可指定每次扩容大小(capacityIncrement变量),当扩容指定大小加上原数组大小,小于可容下大小时扩大到两倍,否则判断是否大于MAX_ARRAY_SIZE。如果大于则扩大到Integer.MAX_VALUE,否则扩大到MAX_ARRAY_SIZE。

注意:这里Integer.MAX_VALUE,与MAX_ARRAY_SIZE的值为什么设置这么大,注释上有写是为了防止内存溢出。

集合原码解读–ArrayList(MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8)

为什么ArrayList的最大数组大小是Integer.MAX_VALUE - 8?

 /**
     * The maximum size of array to allocate.
     * Some VMs reserve some header words in an array.
     * Attempts to allocate larger arrays may result in
     * OutOfMemoryError: Requested array size exceeds VM limit
     */
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    
    //主要扩容方法,minCapacity最小扩容大小值
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        //copy原有数组值
        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;
    }

注意:Vector说的是线程安全的,他是通过synchronized实现方法同步。其实在有些情况下(复合操作)也不是线程安全的参考博客同步容器(如Vector)并不是所有操作都线程安全!:

ArrayList

1.ArrayList 是应用更加广泛的动态数组实现,它本身不是线程安全的,所以性能要好很多。与 Vector 近似,ArrayList 也是可以根据需要调整容量,不过两者的调整逻辑有所区别,Vector 在扩容时会提高 1 倍,而 ArrayList 则是增加 50%。

注意和Vector一样是数组实现,容器扩大的容量不一样,但是最大容量一样

LinkedList

1.双向链表

2.所以它不需要像上面两种那样调整容量,它也不是线程安全的。

对比:

1.Vector 和 ArrayList 作为动态数组,其内部元素以数组形式顺序存储的,所以非常适合随机访问的场合。除了尾部插入和删除元素,往往性能会相对较差,比如我们在中间位置插入一个元素,需要移动后续所有元素。

2. LinkedList 进行节点插入、删除却要高效得多,但是随机访问性能则要比动态数组慢。

需要注意的是ArrayList所说的插入、删除性能相对较差是在非尾部的处理。那么如果只是在尾部处理那么性能是没多大区别的。在平常开发中对自己的数据处理的方式选择合适的集合类。

Vector 和 ArrayList都是数组结构,合理制定大小可以有效提高系统性能。在阿里规范中也有说到指定集合大小。

在一些工具中如Arrays.asList()生成的是不可变的集合,需要注意。

可以通过如:Collections.synchronizedList()方法创建线程安全的集合。如果性能要求不是很高的情况可使用,毕竟这里是通过synchronized实现,控制粒度还是很大。

猜你喜欢

转载自blog.csdn.net/qq_28325291/article/details/84455200