ArrayList、Vector、LinkedList三者

文章目录

    • 一、ArrayList和LinkedList的区别
      • 1.1、ArrayList
      • 1.2、LinkedList
      • 1.3、适用场景分析
      • 1.4、部分源码分析
        • 1.4.1、ArrayList
        • 1.4.2、LinkedList
    • 二、ArrayList和Vector
      • 2.1、Vector的概念
      • 2.2、二者的主要区别
      • 2.3、看一下部分源码
        • 2.3.1、ArrayList的扩容机制源码
        • 2.3.2、Vector的扩容机制源码

一、ArrayList和LinkedList的区别

1.1、ArrayList

  • 优点:ArrayList是实现了基于动态数组的数据结构,因为地址连续,一旦数据存好了,查询操作效率会比较高(在内存中是连着放的)
  • 缺点:因为地址连续,ArrayList要移动数据,所以插入和删除操作效率比较低。

1.2、LinkedList

  • 优点:LinkedList基于链表的数据结构,地址是任意的,所以在开辟内存空间的时候不需要等一个连续的地址。对于新增和删除操作,LinkedList比较占优势。LinkedList适用于头尾操作或插入指定位置的场景。
  • 缺点:因为LinkedList要移动指针,所以查询操作性能比较低。

1.3、适用场景分析

  • 当需要对数据进行随机访问的时候,选用ArrayList
  • 当需要对数据进行多次增加删除修改时,采用LinkedList.
  • 如果容量固定,并且只添加到尾部,不会引起扩容,优先采用ArrayList。
  • 当然,绝大多数业务的场景下,使用ArrayList就够了,但是需要注意避免ArrayList的扩容,以及非顺序的插入。

1.4、部分源码分析

1.4.1、ArrayList

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    private static final long serialVersionUID = 8683452581122892189L;

    /**
     * Default initial capacity.
     */
    private static final int DEFAULT_CAPACITY = 10;

    /**
     * Shared empty array instance used for empty instances.
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};
}

可以看出ArrayList是继承了AbstractList类,实现了List接口。

1.4.2、LinkedList

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
    transient int size = 0;

    /**
     * Pointer to first node.
     * Invariant: (first == null && last == null) ||
     *            (first.prev == null && first.item != null)
     */
    transient Node<E> first;

    /**
     * Pointer to last node.
     * Invariant: (first == null && last == null) ||
     *            (last.next == null && last.item != null)
     */
    transient Node<E> last;

    /**
     * Constructs an empty list.
     */
    public LinkedList() {
    }
}

可以看出LinkedList继承的类是AbstractSequentialList,不光实现了List,还有Deque,是Java提供的双向链表

二、ArrayList和Vector

2.1、Vector的概念

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

2.2、二者的主要区别

  • 就是ArrayList是线程不安全的,Vector是线程安全的
  • 还有就是ArrayList的扩容是原来的1.5倍,而Vector的扩容时原来的2倍
  • 剩下的两者的用法差不多

2.3、看一下部分源码

2.3.1、ArrayList的扩容机制源码


    /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return true (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        // 自动扩容机制的核心
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        // 将元素添加到末尾
        elementData[size++] = e;
        return true;
    }
  /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        // 扩容为原来的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        // 如果扩容1.5倍后还不满足需求,直接扩容为需求值
        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);
    }

2.3.2、Vector的扩容机制源码

public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    /**
     * The array buffer into which the components of the vector are
     * stored. The capacity of the vector is the length of this array buffer,
     * and is at least large enough to contain all the vector's elements.
     *
     * 

Any array elements following the last element in the Vector are null. * * @serial */ protected Object[] elementData; }

继承和实现跟ArrayList差不多

 /**
     * Appends the specified element to the end of this Vector.
     *
     * @param e element to be appended to this Vector
     * @return {@code true} (as specified by {@link Collection#add})
     * @since 1.2
     */
    public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }
/**
     * 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;

    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
         // 扩容为原来的2倍
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        // 如果扩容2倍后还不满足需求,直接扩容为需求值
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

通过对比add方法发现ArrayList的方法没有synchronized,而Vector的add方法有synchronized修饰。不过建议使用ArrayList,因为Vector效率低,有锁机制。

你可能感兴趣的:(笔记)