ArrayList和LinkedList的区别?

2018-11-05  本文已影响0人  simit

arrayList和linkedList都是list接口的实现类,arrayList是基于动态数组实现的,LinkedList是基于双向链表是实现的。
数组是内存中一段连续的存储空间。


未命名文件 (1).png

链表是一种物理存储单元上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构操作复杂(百度百科)。


未命名文件 (2).png
ArrayList和LinkedList的区别主要由三点:
1.arrayList基于动态数组,linkedList基于双向链表。
2.对于get和set操作arrayList优于linkedList

3.对于add和remove操作linkedList优于arrayList
第一个区别显而易见,不再多说。
对于第二个区别:对于get和set操作arrayList优于linkedList
arrayList的get方法

 public E get(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

        return (E) elementData[index];
    }

linkedList的get方法

 public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }
 Node<E> node(int index) {
        // assert isElementIndex(index);

        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }

从实现逻辑上可以看出,arrayList可以直接通过角标获取某个元素,而linkedList需要从第一个开始一个一个找所以更耗时(set方法同理)。
第三个区别:对于add和remove操作linkedList优于arrayList
arrayList的add方法

public void add(int index, E element) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }

linkedList的add方法

  public void add(int index, E element) {
        checkPositionIndex(index);

        if (index == size)
            linkLast(element);
        else
            linkBefore(element, node(index));
    }
  void linkBefore(E e, Node<E> succ) {
        // assert succ != null;
        final Node<E> pred = succ.prev;
        final Node<E> newNode = new Node<>(pred, e, succ);
        succ.prev = newNode;
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        size++;
        modCount++;
    }

arrayList的add方法每次插入都需要copy原数组扩容,copy数组的操作是比较耗时的。
linkedList每次插入需要创建新的节点并指明前驱和后继,保证指针指向正确。copy数组的操作相对这个操作是比较耗时的。

上一篇下一篇

猜你喜欢

热点阅读