Java集合之LinkedList

185 阅读2分钟

一、概述

LinkedList的底层存储结构是双向链表实现的。链表无容量限制,并且在中间插入和删除的效率高于数组,因为它只需要找到该结点,通过将其前一个结点next指向后一个结点,后一个结点的prev指向前一个结点,即可完成删除操作。

但链表结构的缺点在于:

  • 其需要额外的链表指针,用于存储next和prev。
  • 无法直接获得指定位置的节点,只能从头遍历或从尾结点遍历得到对应结点的值。


LinkedList中静态内部类结构:

private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;

    Node(Node<E> prev, E element, Node<E> next) {
       this.item = element;
       this.next = next;
       this.prev = prev;
   }
}


LinkedList结构的简单结构如下:(图片来源于github.com/LRH1993/and…



二、set和get方法

public E set(int index, E element){
   checkElementIndex(index);
   Node<E> x = node(index);
   E oldVal = x.item;
   x.item = element;
   return oldVal;
}

public E get(int index){
   checkElementIndex(index);
   return node(index).item;
}

这两种方法都是调用node()方法,该方法以O(n/2)的性能来获取一个结点。具体如下:

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;
    }
}

即判断从头结点开始遍历查找,还是从尾结点遍历查找该结点,以便提高查找效率。


三、add()方法

  • add(E element);

public boolean add(E e){
   linkLast(e);
   return true;
}

  • add(int index, E element);

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

   if(index == size) 
      linkLast(element);
   else 
      linkBefore(element, node(index));
}

这两种方法插入元素中,要么调用linkLast()方法,要么调用linkBefore()方法,前一种是直接在尾结点出进行插入,后一个方法找到对应的位置node(index)结点,在前前面插入对应的结点。