007Java集合004详解LinkedList

注意:本文基于JDK1.8进行记录。

1 简介

允许任何符合规则的元素插入,包括null和重复元素。

底层是链表结构,使用链表代替索引,查找效率低,增删效率高。

线程不安全。

2 方法说明

2.1 构造方法

1 // 空参构造器。
2 public LinkedList();
3 // 传入了一个集合的构造器。
4 public LinkedList(Collection<? extends E> c);

2.2 常用方法

 1 // 获取个数。
 2 public int size();
 3 // 判断是否包含指定数据。
 4 public boolean contains(Object o);
 5 // 计算指定数据首次出现的下标。
 6 public int indexOf(Object o);
 7 // 计算指定数据最后出现的下标。
 8 public int lastIndexOf(Object o);
 9 // 获取指定下标的元素。
10 public E get(int index);
11 // 获取首节点元素,节点不存在会抛异常。
12 public E getFirst();
13 // 获取尾节点元素,节点不存在会抛异常。
14 public E getLast();
15 // 设置指定下标的指定元素,并返回旧元素。
16 public E set(int index, E element);
17 // 添加指定元素作为尾节点,并返回是否成功。
18 public boolean add(E e);
19 // 在指定位置添加指定元素。
20 public void add(int index, E element);
21 // 添加指定元素作为首节点。
22 public void addFirst(E e);
23 // 添加指定元素作为尾节点。
24 public void addLast(E e);
25 // 删除同指定元素相同的第一个元素,并返回是否成功。
26 public boolean remove(Object o);
27 // 删除指定位置的元素,并返回删除的元素。
28 public E remove(int index);
29 // 删除首节点元素,并返回删除的元素,节点不存在会抛异常。
30 public E removeFirst();
31 // 删除尾节点元素,并返回删除的元素,节点不存在会抛异常。
32 public E removeLast();

2.3 队列方法

 1 // 获取首节点元素,节点不存在会抛异常。
 2 public E element();
 3 // 获取首节点元素,节点不存在会返回null。
 4 public E peek();
 5 // 获取首节点元素,节点不存在会返回null。
 6 public E peekFirst();
 7 // 获取尾节点元素,节点不存在会返回null。
 8 public E peekLast();
 9 // 添加指定元素作为尾节点。
10 public boolean offer(E e);
11 // 添加指定元素作为首节点。
12 public boolean offerFirst(E e);
13 // 添加指定元素作为尾节点。
14 public boolean offerLast(E e);
15 // 删除首节点元素,并返回删除的元素,节点不存在会返回null。
16 public E poll();
17 // 删除首节点元素,并返回删除的元素,节点不存在会返回null。
18 public E pollFirst();
19 // 删除尾节点元素,并返回删除的元素,节点不存在会返回null。
20 public E pollLast();

2.4 栈方法

1 // 添加指定元素作为首节点。
2 public void push(E e);
3 // 删除首节点元素,并返回删除的元素,节点不存在会抛异常。
4 public E pop();

3 源码分析

3.1 属性

1 // 元素个数。
2 transient int size = 0;
3 // 头节点。
4 transient Node<E> first;
5 // 尾节点。
6 transient Node<E> last;

3.2 构造方法

1 // 空参构造器。
2 public LinkedList() {
3 }
4 // 传入了一个集合的构造器。
5 public LinkedList(Collection<? extends E> c) {
6     this();
7     addAll(c);
8 }

3.3 常用方法

  1 // 获取个数。
  2 public int size() {
  3     return size;
  4 }
  5 // 判断是否包含指定数据。
  6 public boolean contains(Object o) {
  7     return indexOf(o) != -1;
  8 }
  9 // 计算指定数据首次出现的下标。
 10 public int indexOf(Object o) {
 11     int index = 0;
 12     // 如果指定数据为null。
 13     if (o == null) {
 14         for (Node<E> x = first; x != null; x = x.next) {
 15             if (x.item == null)
 16                 return index;
 17             index++;
 18         }
 19     // 如果指定数据不为null。
 20     } else {
 21         for (Node<E> x = first; x != null; x = x.next) {
 22             if (o.equals(x.item))
 23                 return index;
 24             index++;
 25         }
 26     }
 27     return -1;
 28 }
 29 // 计算指定数据最后出现的下标。
 30 public int lastIndexOf(Object o) {
 31     int index = size;
 32     // 如果指定数据为null。
 33     if (o == null) {
 34         for (Node<E> x = last; x != null; x = x.prev) {
 35             index--;
 36             if (x.item == null)
 37                 return index;
 38         }
 39     // 如果指定数据不为null。
 40     } else {
 41         for (Node<E> x = last; x != null; x = x.prev) {
 42             index--;
 43             if (o.equals(x.item))
 44                 return index;
 45         }
 46     }
 47     return -1;
 48 }
 49 // 获取指定下标的元素。
 50 public E get(int index) {
 51     // 检查指定下标是否越界。
 52     checkElementIndex(index);
 53     // 遍历链表并获取指定下标对应的元素。
 54     return node(index).item;
 55 }
 56 // 获取首节点元素,节点不存在会抛异常。
 57 public E getFirst() {
 58     final Node<E> f = first;
 59     if (f == null)
 60         throw new NoSuchElementException();
 61     return f.item;
 62 }
 63 // 获取尾节点元素,节点不存在会抛异常。
 64 public E getLast() {
 65     final Node<E> l = last;
 66     if (l == null)
 67         throw new NoSuchElementException();
 68     return l.item;
 69 }
 70 // 设置指定下标的指定元素,并返回旧元素。
 71 public E set(int index, E element) {
 72     // 检查指定下标是否越界。
 73     checkElementIndex(index);
 74     // 遍历链表并获取指定下标对应的元素。
 75     Node<E> x = node(index);
 76     // 获取旧元素。
 77     E oldVal = x.item;
 78     // 替换元素。
 79     x.item = element;
 80     // 返回旧元素。
 81     return oldVal;
 82 }
 83 // 添加指定元素作为尾节点,并返回是否成功。
 84 public boolean add(E e) {
 85     linkLast(e);
 86     return true;
 87 }
 88 // 在指定位置添加指定元素。
 89 public void add(int index, E element) {
 90     // 检查指定下标是否越界。
 91     checkPositionIndex(index);
 92     // 如果指定位置为末尾,则直接末尾插入。
 93     if (index == size)
 94         linkLast(element);
 95     // 如果指定位置不为末尾,则插入到该位置所在的元素前面。
 96     else
 97         linkBefore(element, node(index));
 98 }
 99 // 添加指定元素作为首节点。
100 public void addFirst(E e) {
101     linkFirst(e);
102 }
103 // 添加指定元素作为尾节点。
104 public void addLast(E e) {
105     linkLast(e);
106 }
107 // 删除同指定元素相同的第一个元素,并返回是否成功。
108 public boolean remove(Object o) {
109     if (o == null) {
110         for (Node<E> x = first; x != null; x = x.next) {
111             if (x.item == null) {
112                 unlink(x);
113                 return true;
114             }
115         }
116     } else {
117         for (Node<E> x = first; x != null; x = x.next) {
118             if (o.equals(x.item)) {
119                 unlink(x);
120                 return true;
121             }
122         }
123     }
124     return false;
125 }
126 // 删除指定位置的元素,并返回删除的元素。
127 public E remove(int index) {
128     // 检查指定下标是否越界。
129     checkElementIndex(index);
130     // 找到指定位置的元素并删除。
131     return unlink(node(index));
132 }
133 // 删除首节点元素,并返回删除的元素,节点不存在会抛异常。
134 public E removeFirst() {
135     final Node<E> f = first;
136     if (f == null)
137         throw new NoSuchElementException();
138     return unlinkFirst(f);
139 }
140 // 删除尾节点元素,并返回删除的元素,节点不存在会抛异常。
141 public E removeLast() {
142     final Node<E> l = last;
143     if (l == null)
144         throw new NoSuchElementException();
145     return unlinkLast(l);
146 }

3.4 队列方法

 1 // 获取首节点元素,节点不存在会抛异常。
 2 public E element() {
 3     return getFirst();
 4 }
 5 // 获取首节点元素,节点不存在会返回null。
 6 public E peek() {
 7     final Node<E> f = first;
 8     return (f == null) ? null : f.item;
 9 }
10 // 获取首节点元素,节点不存在会返回null。
11 public E peekFirst() {
12     final Node<E> f = first;
13     return (f == null) ? null : f.item;
14 }
15 // 获取尾节点元素,节点不存在会返回null。
16 public E peekLast() {
17     final Node<E> l = last;
18     return (l == null) ? null : l.item;
19 }
20 // 添加指定元素作为尾节点。
21 public boolean offer(E e) {
22     return add(e);
23 }
24 // 添加指定元素作为首节点。
25 public boolean offerFirst(E e) {
26     addFirst(e);
27     return true;
28 }
29 // 添加指定元素作为尾节点。
30 public boolean offerLast(E e) {
31     addLast(e);
32     return true;
33 }
34 // 删除首节点元素,并返回删除的元素,节点不存在会返回null。
35 public E poll() {
36     final Node<E> f = first;
37     return (f == null) ? null : unlinkFirst(f);
38 }
39 // 删除首节点元素,并返回删除的元素,节点不存在会返回null。
40 public E pollFirst() {
41     final Node<E> f = first;
42     return (f == null) ? null : unlinkFirst(f);
43 }
44 // 删除尾节点元素,并返回删除的元素,节点不存在会返回null。
45 public E pollLast() {
46     final Node<E> l = last;
47     return (l == null) ? null : unlinkLast(l);
48 }

3.5 栈方法

1 // 入栈,添加指定元素作为首节点。
2 public void push(E e) {
3     addFirst(e);
4 }
5 // 出栈,删除首节点元素,并返回删除的元素,节点不存在会抛异常。
6 public E pop() {
7     return removeFirst();
8 }

 

上一篇:Java ArrayList、LinkedList、Vector三者的异同


下一篇:LinkedList源码解析