Fork me on GitHub

Java中LinkedList实现原理

数据结构

  LinkedList是基于链表结构实现,所以在LinkedList类中包含了first和last两个指针(类型为Node)。Node中包含了对prev节点、next节点的引用,这样就构成了双向的链表。

 1   private static class Node<E> {
 2         E item;
 3         Node<E> next;
 4         Node<E> prev;
 5 
 6         Node(Node<E> prev, E element, Node<E> next) {
 7             this.item = element;
 8             this.next = next;
 9             this.prev = prev;
10         }
11     }

存储

1.add(E e)方法

  该方法首先声明一个新Node l,将链表的最后一个Node赋值给l,然后将新的Node即newNode覆盖last(或者说让last指向newNode),最后将l的next指针指向newNode。

 1   //Appends the specified element to the end of this list.
 2     public boolean add(E e) {
 3         linkLast(e);
 4         return true;
 5     }
 6     /**
 7      * Links e as last element.
 8      */
 9     void linkLast(E e) {
10         final Node<E> l = last;
11         final Node<E> newNode = new Node<>(l, e, null);
12         last = newNode;
13         if (l == null)
14             first = newNode;
15         else
16             l.next = newNode;
17         size++;
18         modCount++;
19     }

2.add(int index, E element)

  该方法是在指定的index位置插入新元素。如果index位置正好等于size,则调用linkLast(element)将其插入到末尾;否则调用linkBefore(element, node(index))方法进行插入。

  linkBefore中的node(index)是返回指定位置的元素。

 1   public void add(int index, E element) {
 2         checkPositionIndex(index);
 3         if (index == size)
 4             linkLast(element);
 5         else
 6             linkBefore(element, node(index));
 7     }
 8     /**
 9      * Returns the (non-null) Node at the specified element index.
10      */
11     Node<E> node(int index) {
12         // assert isElementIndex(index);
13         // 如果要取元素的位置是整个list一半的左半边,那么从list的头开始向后遍历,遍历至要取元素的位置
14         if (index < (size >> 1)) {
15             Node<E> x = first;
16             for (int i = 0; i < index; i++)
17                 x = x.next;
18             return x;
19         } 
20         // 否则从list一半的右半边开始寻找,也就是从尾部开始向前遍历,遍历至要取元素的位置
21         else {
22             Node<E> x = last;
23             for (int i = size - 1; i > index; i--)
24                 x = x.prev;
25             return x;
26         }
27     }

删除

1.remove(int index)

  删除列表中指定位置的元素,首先检测该位置是否在该列表中存在,然后解除该元素前、后指向的元素。

 1   public E remove(int index) {
 2         checkElementIndex(index);
 3         return unlink(node(index));
 4     }
 5     E unlink(Node<E> x) {
 6         // assert x != null;
 7         final E element = x.item;
 8         final Node<E> next = x.next;
 9         final Node<E> prev = x.prev;
10 
11         if (prev == null) {
12             first = next;
13         } else {
14             prev.next = next;
15             x.prev = null;
16         }
17 
18         if (next == null) {
19             last = prev;
20         } else {
21             next.prev = prev;
22             x.next = null;
23         }
24 
25         x.item = null;
26         size--;
27         modCount++;
28         return element;
29     }

获取

1.get(int index)

  获取指定位置元素的值。同样首先判断传入位置是否越界,如果超过list的size,抛出IndexOutBoundsException异常,然后node()方法进行左半边或右半边遍历获取,add(int index, E element)中有提到,不再赘述。

1     public E get(int index) {
2         checkElementIndex(index);
3         return node(index).item;
4     }

2.getFirst()

3.getLast()

  first、last是LinkedList的两个属性,判空后直接返回。

 1     /**
 2      * Returns the first element in this list.
 3      *
 4      * @return the first element in this list
 5      * @throws NoSuchElementException if this list is empty
 6      */
 7     public E getFirst() {
 8         final Node<E> f = first;
 9         if (f == null)
10             throw new NoSuchElementException();
11         return f.item;
12     }
13 
14     /**
15      * Returns the last element in this list.
16      *
17      * @return the last element in this list
18      * @throws NoSuchElementException if this list is empty
19      */
20     public E getLast() {
21         final Node<E> l = last;
22         if (l == null)
23             throw new NoSuchElementException();
24         return l.item;
25     }

 

posted @ 2017-02-08 14:20  郑斌blog  阅读(4461)  评论(0编辑  收藏  举报