死磕JDK源码之LinkedList
Posted sakura1027
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了死磕JDK源码之LinkedList相关的知识,希望对你有一定的参考价值。
LinkedList
LinkedList底层是基于双向链表实现的
内置插入删除方法
linkFirst & linkLast
unlinkFirst & unlinkLast
linkBefore
unlink
源码分析
1 package java.util; 2 import java.util.function.Consumer; 3 public class LinkedList<E> extends AbstractSequentialList<E> implements 4 List<E>, Deque<E>, Cloneable, java.io.Serializable { 5 //元素个数 6 transient int size = 0; 7 //第一个节点 8 transient Node<E> first; 9 //最后一个节点 10 transient Node<E> last; 11 //默认构造方法 12 public LinkedList() { 13 } 14 //构造一个包含指定c元素的列表(元素按c迭代器返回的顺序排列) 15 public LinkedList(Collection<? extends E> c) { 16 this(); 17 addAll(c); 18 } 19 //把节点e置为头节点 20 private void linkFirst(E e) { 21 //1.得到第一个节点引用的拷贝 22 final Node<E> f = first; 23 //2.把e的后继节点置为f(添加e之前的第一个节点) 24 final Node<E> newNode = new Node<>(null, e, f); 25 //3.把e置为first 26 first = newNode; 27 //4.如果f为空节点,就把e也置为last,否则把f的前驱节点置为e 28 if (f == null) 29 last = newNode; 30 else 31 f.prev = newNode; 32 //5.size modCount+1 33 size++; 34 modCount++; 35 } 36 //把节点e置为尾节点 37 void linkLast(E e) { 38 final Node<E> l = last; 39 //1.把e的前驱节点置为l(添加e之前的最后一个节点) 40 final Node<E> newNode = new Node<>(l, e, null); 41 //2.把e置为last 42 last = newNode; 43 //3.如果l为空节点,就把e也置为first,否则把l的后继节点置为e 44 if (l == null) 45 first = newNode; 46 else 47 l.next = newNode; 48 size++; 49 modCount++; 50 } 51 //把e放到节点succ之前 52 void linkBefore(E e, Node<E> succ) { 53 //1.记录节点succ的前驱节点为pred 54 final Node<E> pred = succ.prev; 55 //2.把节点e插入succ之前 56 final Node<E> newNode = new Node<>(pred, e, succ); 57 //3.把节点succ的前驱节点置为e 58 succ.prev = newNode; 59 //4.如果pred为空节点,就把e也置为first,否则把pred的后继节点置为e 60 if (pred == null) 61 first = newNode; 62 else 63 pred.next = newNode; 64 size++; 65 modCount++; 66 } 67 //移除头节点f 68 private E unlinkFirst(Node<E> f) { 69 //1.f为第一个节点且f不为空,element为f存放的值 70 final E element = f.item; 71 //2.得到f的下一个节点的一个引用(在f.next置为null之前拷贝一份) 72 final Node<E> next = f.next; 73 //3.把f存放的值和next域置为null 74 f.item = null; 75 f.next = null; 76 //4.把next引用置为first 77 first = next; 78 //5.如果next为空,说明没有元素了,那么把last也置为空 79 if (next == null) 80 last = null; 81 //否则把next的前驱引用置为null 82 else 83 next.prev = null; 84 //6.size-1 modCount+1 85 size--; 86 modCount++; 87 //7.返回被移除的头节点的值 88 return element; 89 } 90 //移除尾节点l 91 private E unlinkLast(Node<E> l) { 92 //得到尾节点存放的值 93 final E element = l.item; 94 //得到尾节点的前一个节点的引用的一份拷贝 95 final Node<E> prev = l.prev; 96 //把尾节点的值置为null 97 l.item = null; 98 //把尾节点的前驱引用置为null 99 l.prev = null; 100 //把prev引用置为last 101 last = prev; 102 //如果prev为空,说明没有元素了,那么把first也置为空 103 if (prev == null) 104 first = null; 105 //否则把prev的后继引用置为null 106 else 107 prev.next = null; 108 size--; 109 modCount++; 110 //返回被移除尾节点的值 111 return element; 112 } 113 //移除x节点,x不为null 114 E unlink(Node<E> x) { 115 //1.得到节点x存放的值 116 final E element = x.item; 117 //2.得到x后继节点引用的一份拷贝 118 final Node<E> next = x.next; 119 //3.得到x前驱节点引用的一份拷贝 120 final Node<E> prev = x.prev; 121 //如果prev为空,即节点x为第一个节点 122 if (prev == null) { 123 first = next; 124 //4.prev不为空,把x前驱节点的next指向x的后继节点 125 } else { 126 prev.next = next; 127 x.prev = null; 128 } 129 //如果next为空,即节点x为最后一个元素 130 if (next == null) { 131 last = prev; 132 //5.next不为空,把x后继节点的prev指向x的前驱节点 133 } else { 134 next.prev = prev; 135 x.next = null; 136 } 137 //6.把x存放的值置为null 138 x.item = null; 139 //7.size-1 modCount+1 140 size--; 141 modCount++; 142 //8.返回被移除节点x的值 143 return element; 144 } 145 //返回列表第一个节点的值 146 public E getFirst() { 147 final Node<E> f = first; 148 if (f == null) 149 throw new NoSuchElementException(); 150 return f.item; 151 } 152 //返回列表最后一个节点的值 153 public E getLast() { 154 final Node<E> l = last; 155 if (l == null) 156 throw new NoSuchElementException(); 157 return l.item; 158 } 159 //移除头节点并返回其值 160 public E removeFirst() { 161 final Node<E> f = first; 162 if (f == null) 163 throw new NoSuchElementException(); 164 return unlinkFirst(f); 165 } 166 //移除尾节点并返回其值 167 public E removeLast() { 168 final Node<E> l = last; 169 if (l == null) 170 throw new NoSuchElementException(); 171 return unlinkLast(l); 172 } 173 //把节点e置为头节点 174 public void addFirst(E e) { 175 linkFirst(e); 176 } 177 //把节点e置为尾节点 178 public void addLast(E e) { 179 linkLast(e); 180 } 181 //判断列表是否包含元素o 182 public boolean contains(Object o) { 183 return indexOf(o) != -1; 184 } 185 //返回元素个数 186 public int size() { 187 return size; 188 } 189 //把节点e添加至列表尾部,添加完成返回true 190 public boolean add(E e) { 191 linkLast(e); 192 return true; 193 } 194 //移除列表中第一次出现的指定元素o,移除完成返回true 195 public boolean remove(Object o) { 196 if (o == null) { 197 for (Node<E> x = first; x != null; x = x.next) { 198 if (x.item == null) { 199 unlink(x); 200 return true; 201 } 202 } 203 } else { 204 for (Node<E> x = first; x != null; x = x.next) { 205 if (o.equals(x.item)) { 206 unlink(x); 207 return true; 208 } 209 } 210 } 211 return false; 212 } 213 //添加集合c中的所有元素至列表尾部(按c中迭代器的顺序) 214 public boolean addAll(Collection<? extends E> c) { 215 return addAll(size, c); 216 } 217 //把集合c中的所有元素插入index处 218 public boolean addAll(int index, Collection<? extends E> c) { 219 //1.索引检查 220 checkPositionIndex(index); 221 //2.把带插入的集合转为数组a,如果a的长度为0,直接返回false 222 Object[] a = c.toArray(); 223 int numNew = a.length; 224 if (numNew == 0) 225 return false; 226 //3.succ为索引为index的节点,pred为索引为index-1的节点 227 Node<E> pred, succ; 228 //4.如果index为size,那么succ为null,pred为last节点 229 if (index == size) { 230 succ = null; 231 pred = last; 232 } else { 233 succ = node(index); 234 pred = succ.prev; 235 } 236 for (Object o : a) { 237 @SuppressWarnings("unchecked") E e = (E) o; 238 //5.建立e节点的pred引用 239 Node<E> newNode = new Node<>(pred, e, null); 240 //6.如果index=0,即pred为空节点就把first置为e 241 if (pred == null) 242 first = newNode; 243 //否则把pred的next引用置为e 244 else 245 pred.next = newNode; 246 pred = newNode; 247 } 248 //7.如果index处为空,就把集合c中的最后一个元素置为last 249 if (succ == null) { 250 last = pred; 251 //否则建立集合c中最后一个元素的next引用为succ,succ的prev引用为pred 252 } else { 253 pred.next = succ; 254 succ.prev = pred; 255 } 256 //8.更新size和modCount 257 size += numNew; 258 modCount++; 259 return true; 260 } 261 //移除所有元素 262 public void clear() { 263 for (Node<E> x = first; x != null;) { 264 Node<E> next = x.next; 265 x.item = null; 266 x.next = null; 267 x.prev = null; 268 x = next; 269 } 270 first = last = null; 271 size = 0; 272 modCount++; 273 } 274 //返回指定位置的元素 275 public E get(int index) { 276 checkElementIndex(index); 277 return node(index).item; 278 } 279 //替换指定index的元素为指定element,并返回被替换的值 280 public E set(int index, E element) { 281 checkElementIndex(index); 282 Node<E> x = node(index); 283 E oldVal = x.item; 284 x.item = element; 285 return oldVal; 286 } 287 //把element插入指定index处 288 public void add(int index, E element) { 289 checkPositionIndex(index); 290 if (index == size) 291 linkLast(element); 292 else 293 linkBefore(element, node(index)); 294 } 295 //移除指定位置的元素 296 public E remove(int index) { 297 checkElementIndex(index); 298 return unlink(node(index)); 299 } 300 //检查index是否越界 301 private boolean isElementIndex(int index) { 302 return index >= 0 && index < size; 303 } 304 //检查index是否越界 305 private boolean isPositionIndex(int index) { 306 return index >= 0 && index <= size; 307 } 308 //索引越界错误处理 309 private String outOfBoundsMsg(int index) { 310 return "Index: " + index + ", Size: " + size; 311 } 312 //索引检查 313 private void checkElementIndex(int index) { 314 if (!isElementIndex(index)) 315 throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); 316 } 317 //索引检查 318 private void checkPositionIndex(int index) { 319 if (!isPositionIndex(index)) 320 throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); 321 } 322 //返回index处的节点 323 Node<E> node(int index) { 324 //index在前半部分从前向后遍历 325 if (index < (size >> 1)) { 326 Node<E> x = first; 327 for (int i = 0; i < index; i++) 328 x = x.next; 329 return x; 330 //否则从后向前遍历 331 } else { 332 Node<E> x = last; 333 for (int i = size - 1; i > index; i--) 334 x = x.prev; 335 return x; 336 } 337 } 338 //返回列表中第一次出现指定元素o的索引,不存在返回-1 339 public int indexOf(Object o) { 340 int index = 0; 341 if (o == null) { 342 for (Node<E> x = first; x != null; x = x.next) { 343 if (x.item == null) 344 return index; 345 index++; 346 } 347 } else { 348 for (Node<E> x = first; x != null; x = x.next) { 349 if (o.equals(x.item)) 350 return index; 351 index++; 352 } 353 } 354 return -1; 355 } 356 //返回列表中最后一次出现指定元素o的索引,不存在返回-1 357 public int lastIndexOf(Object o) { 358 int index = size; 359 if (o == null) { 360 for (Node<E> x = last; x != null; x = x.prev) { 361 index--; 362 if (x.item == null) 363 return index; 364 } 365 } else { 366 for (Node<E> x = last; x != null; x = x.prev) { 367 index--; 368以上是关于死磕JDK源码之LinkedList的主要内容,如果未能解决你的问题,请参考以下文章