LinkedList源码
参考博客: https://blog.csdn.net/eson_15/article/details/51135944
LinkedList与collection的关系:
LinkedList是一个继承与AbatractSequentiaList的双向链表,他也可以被 当作堆栈,队列或双端队列进行操作.
LinkedList实现了List接口,所以能对它进行队列操作.
LinkedList实现了Deque接口,能将LinkedList当作双端队列使用.
LinkedList实现了Serializable接口,所以它也支持序列化,能通过序列化去传输.
LinkedList是线程不安全的
JDK1.7
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 | /*双向链表*/ public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable { transient int size = 0 ; //LinkedList中元素的个数 transient Node<E> first; //链表的头结点 transient Node<E> last; //链表的尾节点 public LinkedList() { //默认构造函数,创建一个空链表 } //按照c中的元素生成一个LinkedList public LinkedList(Collection<? extends E> c) { this (); addAll(c); //将c中的元素添加到空链表的尾部 } /***************************** 添加头结点 ********************************/ public void addFirst(E e) { linkFirst(e); } private void linkFirst(E e) { final Node<E> f = first; //f指向头结点 //生成一个新结点e,其前向指针为null,后向指针为f final Node<E> newNode = new Node<>( null , e, f); first = newNode; //first指向新生成的结点,f保存着老的头结点信息 if (f == null ) last = newNode; //如果f为null,则表示整个链表目前是空的,则尾结点也指向新结点 else f.prev = newNode; size++; modCount++; //修改次数+1 } (我自己有点懵) 所以画了个图,偏于理解 /****************** 添加尾节点,与上面添加头结点原理一样 ******************/ public void addLast(E e) { linkLast(e); } void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null ); last = newNode; if (l == null ) first = newNode; else l.next = newNode; size++; modCount++; } /****************** 在非空节点succ之前插入新节点e ************************/ void linkBefore(E e, Node<E> succ) { // assert succ != null; //外界调用需保证succ不为null,否则程序会抛出空指针异常 final Node<E> pred = succ.prev; //生成一个新结点e,其前向指针指向pred,后向指针指向succ final Node<E> newNode = new Node<>(pred, e, succ); succ.prev = newNode; //succ的前向指针指向newNode if (pred == null ) //如果pred为null,则表示succ为头结点,此时头结点指向最新生成的结点newNode first = newNode; else //pred的后向指针指向新生成的结点,此时已经完成了结点的插入操作 pred.next = newNode; size++; modCount++; } /*********************** 删除头结点,并返回头结点的值 *********************/ public E removeFirst() { final Node<E> f = first; if (f == null ) throw new NoSuchElementException(); return unlinkFirst(f); //private方法 } private E unlinkFirst(Node<E> f) { // assert f == first && f != null; //需确保f为头结点,且链表不为Null final E element = f.item; //获得节点的值 final Node<E> next = f.next; //获得头结点下一个节点 f.item = null ; f.next = null ; first = next; if (next == null ) //如果next为null,则表示f为last结点,此时链表即为空链表 last = null ; else //修改next的前向指针,因为first结点的前向指针为null next.prev = null ; size--; modCount++; return element; } /********************** 删除尾节点,并返回尾节点的值 ********************/ public E removeLast() { final Node<E> l = last; if (l == null ) throw new NoSuchElementException(); return unlinkLast(l); //private方法 } private E unlinkLast(Node<E> l) { // assert l == last && l != null; final E element = l.item; final Node<E> prev = l.prev; l.item = null ; l.prev = null ; last = prev; if (prev == null ) first = null ; else prev.next = null ; size--; modCount++; return element; } /******************** 删除为空节点x,并返回该节点的值 ******************/ E unlink(Node<E> x) { // assert x != null; //需确保x不为null,否则后续操作会抛出空指针异常 final E element = x.item; final Node<E> next = x.next; final Node<E> prev = x.prev; if (prev == null ) { //如果prev为空,则x结点为first结点,此时first结点指向next结点(x的后向结点) first = next; } else { prev.next = next; //x的前向结点的后向指针指向x的后向结点 x.prev = null ; //释放x的前向指针 } if (next == null ) { //如果next结点为空,则x结点为尾部结点,此时last结点指向prev结点(x的前向结点) last = prev; } else { next.prev = prev; //x的后向结点的前向指针指向x的前向结点 x.next = null ; //释放x的后向指针 } x.item = null ; //释放x的值节点,此时x节点可以完全被GC回收 size--; modCount++; return element; } /********************** 获得头结点的值 ********************/ public E getFirst() { final Node<E> f = first; if (f == null ) throw new NoSuchElementException(); return f.item; } /********************** 获得尾结点的值 ********************/ public E getLast() { final Node<E> l = last; if (l == null ) throw new NoSuchElementException(); return l.item; } /*************** 判断元素(值为o)是否在链表中 *************/ public boolean contains(Object o) { return indexOf(o) != - 1 ; //定位元素 } //返回元素个数 public int size() { return size; } //向链表尾部添加元素e public boolean add(E e) { linkLast(e); return true ; } /*************** 删除值为o的元素 *************/ public boolean remove(Object o) { if (o == null ) { for (Node<E> x = first; x != null ; x = x.next) { if (x.item == null ) { //找到即返回 unlink(x); return true ; } } } else { //o不为空 for (Node<E> x = first; x != null ; x = x.next) { if (o.equals(x.item)) { unlink(x); return true ; } } } return false ; } /*************** 将集合e中所有元素添加到链表中 *************/ public boolean addAll(Collection<? extends E> c) { return addAll(size, c); } //从index开始,向后添加的 public boolean addAll( int index, Collection<? extends E> c) { checkPositionIndex(index); //判断index是否越界 Object[] a = c.toArray(); //将集合c转换为数组 int numNew = a.length; if (numNew == 0 ) return false ; Node<E> pred, succ; if (index == size) { //即index个节点在尾节点后面 succ = null ; pred = last; //pred指向尾节点 } else { succ = node(index); //succ指向第index个节点 pred = succ.prev; //pred指向succ的前向节点 } //for循环结束后,a里面的元素都添加到当前链表里了,向后添加 for (Object o : a) { @SuppressWarnings ( "unchecked" ) E e = (E) o; Node<E> newNode = new Node<>(pred, e, null ); if (pred == null ) first = newNode; //如果pred为null,则succ为头结点 else pred.next = newNode; //pred的后向指针指向新节点 pred = newNode; //pred指向新节点,即往后移动一个节点,用于下一次循环 } if (succ == null ) { //succ为null表示index为尾节点之后 last = pred; } else { //pred表示所有元素添加好之后的最后那个节点,此时pred的后向指针指向之前记录的节点,即index处的节点 pred.next = succ; succ.prev = pred; //之前记录的结点指向添加元素之后的最后结点 } size += numNew; modCount++; return true ; } /******************** 清空链表 *************************/ public void clear() { for (Node<E> x = first; x != null ; ) { Node<E> next = x.next; x.item = null ; //释放值结点,便于GC回收 x.next = null ; //释放前向指针 x.prev = null ; //释放前后指针 x = next; //后向遍历 } first = last = null ; //释放头尾节点 size = 0 ; modCount++; } /******************* Positional Access Operations ***********************/ //获得第index个节点的值 public E get( int index) { checkElementIndex(index); return node(index).item; } //设置第index元素的值 public E set( int index, E element) { checkElementIndex(index); Node<E> x = node(index); E oldVal = x.item; x.item = element; return oldVal; } //在index个节点之前添加新的节点 public void add( int index, E element) { checkPositionIndex(index); if (index == size) linkLast(element); else linkBefore(element, node(index)); } //删除第index个节点 public E remove( int index) { checkElementIndex(index); return unlink(node(index)); } //判断index是否为链表中的元素下标 private boolean isElementIndex( int index) { return index >= 0 && index < size; } //判断index是否为链表中的元素下标。。。包含了size private boolean isPositionIndex( int index) { return index >= 0 && index <= size; } private String outOfBoundsMsg( int index) { return "Index: " +index+ ", Size: " +size; } private void checkElementIndex( int index) { if (!isElementIndex(index)) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private void checkPositionIndex( int index) { if (!isPositionIndex(index)) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } //定位index处的节点 Node<E> node( int index) { // assert isElementIndex(index); //index<size/2时,从头开始找 if (index < (size >> 1 )) { Node<E> x = first; for ( int i = 0 ; i < index; i++) x = x.next; return x; } else { //index>=size/2时,从尾开始找 Node<E> x = last; for ( int i = size - 1 ; i > index; i--) x = x.prev; return x; } } /*************************** Search Operations *************************/ //返回首次出现指定元素值o的节点索引 public int indexOf(Object o) { int index = 0 ; if (o == null ) { for (Node<E> x = first; x != null ; x = x.next) { if (x.item == null ) return index; index++; } } else { for (Node<E> x = first; x != null ; x = x.next) { if (o.equals(x.item)) return index; index++; } } return - 1 ; //没有则返回-1 } //返回最后一次出现指定元素值o的节点索引 public int lastIndexOf(Object o) { int index = size; if (o == null ) { for (Node<E> x = last; x != null ; x = x.prev) { index--; if (x.item == null ) return index; } } else { for (Node<E> x = last; x != null ; x = x.prev) { index--; if (o.equals(x.item)) return index; } } return - 1 ; } /***************************** Queue operations ***********************/ //下面是与栈和队列相关的操作了 //实现栈的操作,返回第一个元素的值 public E peek() { final Node<E> f = first; return (f == null ) ? null : f.item; //不删除 } //实现队列操作,返回第一个节点 public E element() { return getFirst(); } //实现栈的操作,弹出第一个节点 public E poll() { final Node<E> f = first; return (f == null ) ? null : unlinkFirst(f); //删除 } //实现队列操作,删除节点 public E remove() { return removeFirst(); } //添加节点 public boolean offer(E e) { return add(e); } /************************* Deque operations **********************/ //下面都是和双端队列相关的操作了 //添加头结点 public boolean offerFirst(E e) { addFirst(e); return true ; } //添加尾节点 public boolean offerLast(E e) { addLast(e); return true ; } //返回头结点的值 public E peekFirst() { final Node<E> f = first; return (f == null ) ? null : f.item; } //返回尾节点的值 public E peekLast() { final Node<E> l = last; return (l == null ) ? null : l.item; } //弹出头结点 public E pollFirst() { final Node<E> f = first; return (f == null ) ? null : unlinkFirst(f); //删除 } //弹出尾节点 public E pollLast() { final Node<E> l = last; return (l == null ) ? null : unlinkLast(l); //删除 } //栈操作,添加头结点 public void push(E e) { addFirst(e); } //栈操作,删除头结点 public E pop() { return removeFirst(); } //删除第一次出现o的节点 public boolean removeFirstOccurrence(Object o) { return remove(o); } //删除最后一次出现o的节点 public boolean removeLastOccurrence(Object o) { if (o == null ) { for (Node<E> x = last; x != null ; x = x.prev) { if (x.item == null ) { unlink(x); return true ; } } } else { for (Node<E> x = last; x != null ; x = x.prev) { if (o.equals(x.item)) { unlink(x); return true ; } } } return false ; } /************************* ListIterator ***********************/ public ListIterator<E> listIterator( int index) { checkPositionIndex(index); return new ListItr(index); //ListItr是一个双向迭代器 } //实现双向迭代器 private class ListItr implements ListIterator<E> { private Node<E> lastReturned = null ; //记录当前节点信息 private Node<E> next; //当前节点的后向节点 private int nextIndex; //当前节点的索引 private int expectedModCount = modCount; //修改次数 ListItr( int index) { // assert isPositionIndex(index); next = (index == size) ? null : node(index); nextIndex = index; } public boolean hasNext() { return nextIndex < size; } public E next() { checkForComodification(); if (!hasNext()) throw new NoSuchElementException(); lastReturned = next; //记录当前节点 next = next.next; //向后移动一个位置 nextIndex++; //节点索引+1 return lastReturned.item; //返回当前节点的值 } public boolean hasPrevious() { return nextIndex > 0 ; } //返回前向节点的值 public E previous() { checkForComodification(); if (!hasPrevious()) throw new NoSuchElementException(); lastReturned = next = (next == null ) ? last : next.prev; nextIndex--; return lastReturned.item; } public int nextIndex() { //返回当前节点的索引 return nextIndex; } public int previousIndex() { //返回当前节点的前一个索引 return nextIndex - 1 ; } public void remove() { //删除当前节点 checkForComodification(); if (lastReturned == null ) throw new IllegalStateException(); Node<E> lastNext = lastReturned.next; unlink(lastReturned); if (next == lastReturned) next = lastNext; else nextIndex--; lastReturned = null ; expectedModCount++; } public void set(E e) { //设置当前节点的值 if (lastReturned == null ) throw new IllegalStateException(); checkForComodification(); lastReturned.item = e; } //在当前节点前面插入新节点信息 public void add(E e) { checkForComodification(); lastReturned = null ; if (next == null ) linkLast(e); else linkBefore(e, next); nextIndex++; expectedModCount++; } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } 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; } } //返回前向迭代器 public Iterator<E> descendingIterator() { return new DescendingIterator(); } //通过ListItr.previous来提供前向迭代器,方向与原来相反 private class DescendingIterator implements Iterator<E> { private final ListItr itr = new ListItr(size()); public boolean hasNext() { return itr.hasPrevious(); } public E next() { return itr.previous(); } public void remove() { itr.remove(); } } @SuppressWarnings ( "unchecked" ) private LinkedList<E> superClone() { try { return (LinkedList<E>) super .clone(); } catch (CloneNotSupportedException e) { throw new InternalError(); } } //克隆操作,执行浅拷贝,只复制引用,没有复制引用指向的内存 public Object clone() { LinkedList<E> clone = superClone(); // Put clone into "virgin" state clone.first = clone.last = null ; clone.size = 0 ; clone.modCount = 0 ; // Initialize clone with our elements for (Node<E> x = first; x != null ; x = x.next) clone.add(x.item); return clone; } /*************************** toArray ****************************/ //返回LinkedList的Object[]数组 public Object[] toArray() { Object[] result = new Object[size]; int i = 0 ; for (Node<E> x = first; x != null ; x = x.next) result[i++] = x.item; return result; } //返回LinkedList的模板数组,存储在a中 @SuppressWarnings ( "unchecked" ) public <T> T[] toArray(T[] a) { if (a.length < size) //如果a的大小 < LinkedList的元素个数,意味着数组a不能容纳LinkedList的全部元素 //则新建一个T[]数组,T[]的大小为LinkedList大小,并将T[]赋给a a = (T[])java.lang.reflect.Array.newInstance( a.getClass().getComponentType(), size); //如果a大小够容纳LinkedList的全部元素 int i = 0 ; Object[] result = a; for (Node<E> x = first; x != null ; x = x.next) result[i++] = x.item; if (a.length > size) a[size] = null ; return a; } private static final long serialVersionUID = 876323262645176354L; /************************* Serializable **************************/ //java.io.Serializable的写入函数 //将LinkedList的“容量,所有元素值”写入到输出流中 private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { // Write out any hidden serialization magic s.defaultWriteObject(); // Write out size s.writeInt(size); //写入容量 // Write out all elements in the proper order. for (Node<E> x = first; x != null ; x = x.next) //写入所有数据 s.writeObject(x.item); } //java.io.Serializable的读取函数:根据写入方式反向读出 //先将LinkedList的“容量”读出,然后将“所有元素值”读出 @SuppressWarnings ( "unchecked" ) private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in any hidden serialization magic s.defaultReadObject(); // Read in size int size = s.readInt(); //读出容量 // Read in all elements in the proper order. for ( int i = 0 ; i < size; i++) //读出所有元素值 linkLast((E)s.readObject()); } } |

关于http协议
分类:
阅读JDK源码
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!