标签:== 堆栈 tee author ast 反序 iter tin 克隆
1. LinkedList的定义
1.1 继承于AbstractSequentialList的双向链表,可以被当作堆栈
、队列
或双端队列
进行操作
1.2 有序,非线程安全的双向链表,默认使用尾部插入法
1.3 适用于频繁新增或删除场景,频繁访问场景请选用ArrayList
1.4 插入和删除时间复杂为O(1),其余最差O(n)
1.5 由于实现Deque接口,双端队列相关方法众多
2. LinkedList的继承体系
AbstractSequentialList
,能被当作堆栈、队列或双端队列进行操作List
接口,能进行队列操作Deque
接口,能将LinkedList当作双端队列使用Cloneable
接口,重写 clone()
,能克隆(浅拷贝)java.io.Serializable
接口,支持序列化3. LinkedList的源码实现
1 public class LinkedList<E> 2 extends AbstractSequentialList<E> 3 implements List<E>, Deque<E>, Cloneable, java.io.Serializable { 4 5 /** 6 * 记录当前链表中元素的个数 7 */ 8 transient int size = 0; 9 10 /** 11 * Pointer to first node. 12 * Invariant: (first == null && last == null) || 13 * (first.prev == null && first.item != null) 14 * 链表的头部节点 15 */ 16 transient Node<E> first; 17 18 /** 19 * Pointer to last node. 20 * Invariant: (first == null && last == null) || 21 * (last.next == null && last.item != null) 22 * 链表的尾部节点 23 */ 24 transient Node<E> last; 25 26 /** 27 * Constructs an empty list. 28 * 默认空构造器 -- 注意LinkedList并不提供指定容量的构造器 29 */ 30 public LinkedList() { 31 } 32 33 /** 34 * 支持将一个Collection对象转换为linkedList对象 35 */ 36 public LinkedList(Collection<? extends E> c) { 37 this(); 38 addAll(c); 39 } 40 41 /** 42 * 从头部开始添加一个元素 43 */ 44 private void linkFirst(E e) { 45 //获取头部节点 46 final Node<E> f = first; 47 48 //组建新的节点,新的节点的prev为null,并赋值给头部节点 49 final Node<E> newNode = new Node<>(null, e, f); 50 first = newNode; 51 52 //头节点==null.说明链表中没有元素 53 if (f == null) 54 last = newNode; 55 else 56 f.prev = newNode; //设置旧的头节点的前一个节点为新建的节点 57 size++; 58 modCount++; 59 } 60 61 /** 62 * Links e as last element. 63 * 从尾部开始添加一个元素 64 */ 65 void linkLast(E e) { 66 67 //获取尾部节点 68 final Node<E> l = last; 69 70 //组建新的节点,新节点的next节点为null,并将新的节点赋值给尾部节点 71 final Node<E> newNode = new Node<>(l, e, null); 72 last = newNode; 73 74 //尾部节点为null,说明链表中没有元素 75 if (l == null) 76 first = newNode; 77 else 78 l.next = newNode; //设置旧的尾节点的next为新建的节点 79 size++; 80 modCount++; 81 } 82 83 /** 84 * 在指定的节点之前添加元素 85 */ 86 void linkBefore(E e, Node<E> succ) { 87 88 //获取指定节点的prev 89 final Node<E> pred = succ.prev; 90 91 //构建新的节点 92 final Node<E> newNode = new Node<>(pred, e, succ); 93 //将新建的节点设置为指定节点的prev 94 succ.prev = newNode; 95 96 //判断prev是否为头结点 97 if (pred == null) 98 first = newNode; 99 else 100 pred.next = newNode; //设置新节点为prev的next节点 101 size++; 102 modCount++; 103 } 104 105 /** 106 * 移除头部节点 107 */ 108 private E unlinkFirst(Node<E> f) { 109 // assert f == first && f != null; 110 final E element = f.item; 111 112 //获取头节点的next,并赋值给first 113 final Node<E> next = f.next; 114 f.item = null; 115 f.next = null; // help GC 116 first = next; 117 118 //next == null,说明链表中已经没有元素 119 if (next == null) 120 last = null; 121 else 122 next.prev = null; //设置头结点的prev为null 123 size--; 124 modCount++; 125 return element; 126 } 127 128 /** 129 * 移除尾部节点 130 */ 131 private E unlinkLast(Node<E> l) { 132 // assert l == last && l != null; 133 final E element = l.item; 134 135 //获取尾部节点的prev节点,并赋值为last节点 136 final Node<E> prev = l.prev; 137 l.item = null; 138 l.prev = null; // help GC 139 last = prev; 140 141 //prev == null,说明链表中已经没有元素 142 if (prev == null) 143 first = null; 144 else 145 prev.next = null; //设置尾节点的next为空 146 size--; 147 modCount++; 148 return element; 149 } 150 151 /** 152 * 移除链表中的某个节点 153 */ 154 E unlink(Node<E> x) { 155 156 //获取要移除的元素 157 final E element = x.item; 158 final Node<E> next = x.next; 159 final Node<E> prev = x.prev; 160 161 //要移除的节点是否是头结点 162 if (prev == null) { 163 first = next; 164 } else { 165 //把当前节点的prev节点的next节点赋值为当前节点的next 166 prev.next = next; 167 //当前节点的prev置为null 168 x.prev = null; 169 } 170 171 //要移除的节点是否是尾节点 172 if (next == null) { 173 last = prev; 174 } else { 175 //当前节点的next节点的prev节点赋值为当前节点的prev 176 next.prev = prev; 177 x.next = null; 178 } 179 180 //将当前节点置为null 181 x.item = null; 182 size--; 183 modCount++; 184 return element; 185 } 186 187 /** 188 * 获取链表中的第一个元素 189 */ 190 public E getFirst() { 191 final Node<E> f = first; 192 if (f == null) 193 throw new NoSuchElementException(); 194 return f.item; 195 } 196 197 /** 198 * 获取链表中的最后一个元素 199 */ 200 public E getLast() { 201 final Node<E> l = last; 202 if (l == null) 203 throw new NoSuchElementException(); 204 return l.item; 205 } 206 207 /** 208 * 移除链表中的第一个元素并返回 209 */ 210 public E removeFirst() { 211 final Node<E> f = first; 212 if (f == null) 213 throw new NoSuchElementException(); 214 215 //执行移除头部节点的方法 216 return unlinkFirst(f); 217 } 218 219 /** 220 * 移除链表中的最后一个元素并返回 221 */ 222 public E removeLast() { 223 final Node<E> l = last; 224 if (l == null) 225 throw new NoSuchElementException(); 226 227 //执行移除尾部节点的方法 228 return unlinkLast(l); 229 } 230 231 /** 232 * 在链表的头部添加节点 233 */ 234 public void addFirst(E e) { 235 linkFirst(e); 236 } 237 238 /** 239 * 在链表的尾部添加节点 240 */ 241 public void addLast(E e) { 242 linkLast(e); 243 } 244 245 /** 246 * 链表中是否包含某个元素 247 */ 248 public boolean contains(Object o) { 249 return indexOf(o) != -1; 250 } 251 252 /** 253 * 链表中元素的个数 254 */ 255 public int size() { 256 return size; 257 } 258 259 /** 260 * 添加一个元素到链表中 261 * 默认是尾部添加 262 * 成功则返回true 263 */ 264 public boolean add(E e) { 265 linkLast(e); 266 return true; 267 } 268 269 /** 270 * 移除链表中的某个元素 271 */ 272 public boolean remove(Object o) { 273 if (o == null) { 274 //遍历查找null元素,并进行移除 275 for (Node<E> x = first; x != null; x = x.next) { 276 if (x.item == null) { 277 //执行移除的方法 278 unlink(x); 279 return true; 280 } 281 } 282 } else { 283 //遍历找到要移除的元素 284 for (Node<E> x = first; x != null; x = x.next) { 285 if (o.equals(x.item)) { 286 //执行移除的方法 287 unlink(x); 288 return true; 289 } 290 } 291 } 292 return false; 293 } 294 295 /** 296 * 将一个collection对象转换为链表中的节点 297 */ 298 public boolean addAll(Collection<? extends E> c) { 299 return addAll(size, c); 300 } 301 302 /** 303 * 304 */ 305 public boolean addAll(int index, Collection<? extends E> c) { 306 307 //检查索引的合理性 308 checkPositionIndex(index); 309 310 //将collection对象转换为数组,数组为空则直接返回 311 Object[] a = c.toArray(); 312 int numNew = a.length; 313 if (numNew == 0) 314 return false; 315 316 //判断是在指定位置插入节点还是在尾部插入节点 317 Node<E> pred, succ; 318 if (index == size) { 319 succ = null; 320 pred = last; 321 } else { 322 succ = node(index); 323 pred = succ.prev; 324 } 325 326 //遍历数组,进行插入 327 for (Object o : a) { 328 @SuppressWarnings("unchecked") E e = (E) o; 329 Node<E> newNode = new Node<>(pred, e, null); 330 //判断链表书否为空 331 if (pred == null) 332 first = newNode; 333 else 334 pred.next = newNode; 335 pred = newNode; 336 } 337 338 //如果succ为null,则是在尾部进行节点的插入 339 if (succ == null) { 340 last = pred; 341 } else { 342 //将新插入的节点和后面的节点进行链接 343 pred.next = succ; 344 succ.prev = pred; 345 } 346 347 size += numNew; 348 modCount++; 349 return true; 350 } 351 352 /** 353 * 清空链表中的元素 354 */ 355 public void clear() { 356 357 //循环设置链表的值为null,加快gc 358 for (Node<E> x = first; x != null; ) { 359 Node<E> next = x.next; 360 x.item = null; 361 x.next = null; 362 x.prev = null; 363 x = next; 364 } 365 first = last = null; 366 size = 0; 367 modCount++; 368 } 369 370 /** 371 * 获取指定位置的元素 372 */ 373 public E get(int index) { 374 //检查索引的合理性 375 checkElementIndex(index); 376 return node(index).item; 377 } 378 379 /** 380 * 替换指定位置上的元素并返回旧的元素 381 */ 382 public E set(int index, E element) { 383 checkElementIndex(index); 384 //找到指定元素所在的节点 385 Node<E> x = node(index); 386 E oldVal = x.item; 387 x.item = element; 388 return oldVal; 389 } 390 391 /** 392 * 在指定的位置添加元素 393 */ 394 public void add(int index, E element) { 395 checkPositionIndex(index); 396 397 if (index == size) 398 linkLast(element); 399 else 400 linkBefore(element, node(index)); 401 } 402 403 /** 404 * 移除指定位置的元素 405 */ 406 public E remove(int index) { 407 //检查索引的合理性 408 checkElementIndex(index); 409 //进行指定位置上的节点移除 410 return unlink(node(index)); 411 } 412 413 414 private boolean isElementIndex(int index) { 415 return index >= 0 && index < size; 416 } 417 418 private boolean isPositionIndex(int index) { 419 return index >= 0 && index <= size; 420 } 421 422 private String outOfBoundsMsg(int index) { 423 return "Index: "+index+", Size: "+size; 424 } 425 426 /** 427 * 检查索引是否合理 428 * @param index 429 */ 430 private void checkElementIndex(int index) { 431 if (!isElementIndex(index)) 432 throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); 433 } 434 435 436 private void checkPositionIndex(int index) { 437 if (!isPositionIndex(index)) 438 throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); 439 } 440 441 /** 442 * 返回某个位置上的节点元素 443 */ 444 Node<E> node(int index) { 445 446 //二分查找 447 if (index < (size >> 1)) { 448 Node<E> x = first; 449 for (int i = 0; i < index; i++) 450 x = x.next; 451 return x; 452 } else { 453 Node<E> x = last; 454 for (int i = size - 1; i > index; i--) 455 x = x.prev; 456 return x; 457 } 458 } 459 460 /** 461 * 元素存在于链表中,则返回所在的节点的位置 462 * 否则返回-1 463 */ 464 public int indexOf(Object o) { 465 //初始化为0 466 int index = 0; 467 //如果元素为null,返回第一个查找到的null的位置 468 if (o == null) { 469 //遍历链表,查找null元素,并增加index的值 470 for (Node<E> x = first; x != null; x = x.next) { 471 if (x.item == null) 472 return index; 473 index++; 474 } 475 } else { 476 //遍历链表,查找元素,并增加index的值 477 for (Node<E> x = first; x != null; x = x.next) { 478 if (o.equals(x.item)) 479 return index; 480 index++; 481 } 482 } 483 return -1; 484 } 485 486 /** 487 * 从链表的尾节点开始查找指定的元素 488 * 并返回指定元素的位置 489 * 没有找到返回-1 490 */ 491 public int lastIndexOf(Object o) { 492 int index = size; 493 //指定的元素是否为null 494 if (o == null) { 495 //遍历查找null元素 496 for (Node<E> x = last; x != null; x = x.prev) { 497 index--; 498 if (x.item == null) 499 return index; 500 } 501 } else { 502 //遍历查找指定的元素 503 for (Node<E> x = last; x != null; x = x.prev) { 504 index--; 505 if (o.equals(x.item)) 506 return index; 507 } 508 } 509 return -1; 510 } 511 512 /** 513 * 进行出队列的操作 514 */ 515 public E peek() { 516 final Node<E> f = first; 517 return (f == null) ? null : f.item; 518 } 519 520 /** 521 * 获取链表中的一个元素 522 * 默认返回头结点的元素 523 */ 524 public E element() { 525 return getFirst(); 526 } 527 528 /** 529 * 进行出队列的操作 530 * 并移除元素 531 */ 532 public E poll() { 533 final Node<E> f = first; 534 return (f == null) ? null : unlinkFirst(f); 535 } 536 537 /** 538 * 移除链表中的元素 539 * 默认为头结点的元素 540 */ 541 public E remove() { 542 return removeFirst(); 543 } 544 545 /** 546 * 添加元素,默认在尾部添加 547 */ 548 public boolean offer(E e) { 549 return add(e); 550 } 551 552 553 /** 554 * 在链表的头部添加元素 555 * 成功则返回true 556 */ 557 public boolean offerFirst(E e) { 558 addFirst(e); 559 return true; 560 } 561 562 /** 563 * 在尾部添加元素 564 */ 565 public boolean offerLast(E e) { 566 addLast(e); 567 return true; 568 } 569 570 /** 571 * 获取第一个元素 572 */ 573 public E peekFirst() { 574 final Node<E> f = first; 575 return (f == null) ? null : f.item; 576 } 577 578 /** 579 * 获取最后一个元素 580 */ 581 public E peekLast() { 582 final Node<E> l = last; 583 return (l == null) ? null : l.item; 584 } 585 586 /** 587 * 获取第一个元素 588 * 并移除 589 */ 590 public E pollFirst() { 591 final Node<E> f = first; 592 return (f == null) ? null : unlinkFirst(f); 593 } 594 595 /** 596 * 获取最后一个元素 597 * 并移除 598 */ 599 public E pollLast() { 600 final Node<E> l = last; 601 return (l == null) ? null : unlinkLast(l); 602 } 603 604 /** 605 * 头部添加元素 606 */ 607 public void push(E e) { 608 addFirst(e); 609 } 610 611 /** 612 * 移除头部元素 613 */ 614 public E pop() { 615 return removeFirst(); 616 } 617 618 /** 619 * 从头查找,并移除指定的元素 620 * 成功返回true 621 */ 622 public boolean removeFirstOccurrence(Object o) { 623 return remove(o); 624 } 625 626 /** 627 * 从尾部查找,并移除指定的元素 628 * 成功返回true 629 */ 630 public boolean removeLastOccurrence(Object o) { 631 if (o == null) { 632 //遍历查找指定的null元素 633 for (Node<E> x = last; x != null; x = x.prev) { 634 if (x.item == null) { 635 unlink(x); 636 return true; 637 } 638 } 639 } else { 640 //遍历查找指定的元素 641 for (Node<E> x = last; x != null; x = x.prev) { 642 if (o.equals(x.item)) { 643 unlink(x); 644 return true; 645 } 646 } 647 } 648 return false; 649 } 650 651 /** 652 * 从指定位置开始获取链表的迭代器 653 */ 654 public ListIterator<E> listIterator(int index) { 655 checkPositionIndex(index); 656 return new ListItr(index); 657 } 658 659 /** 660 * 链表的内部类 661 * 一个迭代器对象 662 * @author Administrator 663 * 664 */ 665 private class ListItr implements ListIterator<E> { 666 private Node<E> lastReturned; 667 private Node<E> next; 668 private int nextIndex; 669 private int expectedModCount = modCount; 670 671 ListItr(int index) { 672 // assert isPositionIndex(index); 673 next = (index == size) ? null : node(index); 674 nextIndex = index; 675 } 676 677 public boolean hasNext() { 678 return nextIndex < size; 679 } 680 681 public E next() { 682 checkForComodification(); 683 if (!hasNext()) 684 throw new NoSuchElementException(); 685 686 lastReturned = next; 687 next = next.next; 688 nextIndex++; 689 return lastReturned.item; 690 } 691 692 public boolean hasPrevious() { 693 return nextIndex > 0; 694 } 695 696 public E previous() { 697 checkForComodification(); 698 if (!hasPrevious()) 699 throw new NoSuchElementException(); 700 701 lastReturned = next = (next == null) ? last : next.prev; 702 nextIndex--; 703 return lastReturned.item; 704 } 705 706 public int nextIndex() { 707 return nextIndex; 708 } 709 710 public int previousIndex() { 711 return nextIndex - 1; 712 } 713 714 public void remove() { 715 checkForComodification(); 716 if (lastReturned == null) 717 throw new IllegalStateException(); 718 719 Node<E> lastNext = lastReturned.next; 720 unlink(lastReturned); 721 if (next == lastReturned) 722 next = lastNext; 723 else 724 nextIndex--; 725 lastReturned = null; 726 expectedModCount++; 727 } 728 729 public void set(E e) { 730 if (lastReturned == null) 731 throw new IllegalStateException(); 732 checkForComodification(); 733 lastReturned.item = e; 734 } 735 736 public void add(E e) { 737 checkForComodification(); 738 lastReturned = null; 739 if (next == null) 740 linkLast(e); 741 else 742 linkBefore(e, next); 743 nextIndex++; 744 expectedModCount++; 745 } 746 747 public void forEachRemaining(Consumer<? super E> action) { 748 Objects.requireNonNull(action); 749 while (modCount == expectedModCount && nextIndex < size) { 750 action.accept(next.item); 751 lastReturned = next; 752 next = next.next; 753 nextIndex++; 754 } 755 checkForComodification(); 756 } 757 758 final void checkForComodification() { 759 if (modCount != expectedModCount) 760 throw new ConcurrentModificationException(); 761 } 762 } 763 764 /** 765 * 链表中保存的节点对象 766 * @param <E> 767 */ 768 private static class Node<E> { 769 E item; //当前元素 770 Node<E> next; //下一个元素 771 Node<E> prev; //上一个元素 772 773 Node(Node<E> prev, E element, Node<E> next) { 774 this.item = element; 775 this.next = next; 776 this.prev = prev; 777 } 778 } 779 780 /** 781 * @since 1.6 782 */ 783 public Iterator<E> descendingIterator() { 784 return new DescendingIterator(); 785 } 786 787 /** 788 * Adapter to provide descending iterators via ListItr.previous 789 */ 790 private class DescendingIterator implements Iterator<E> { 791 private final ListItr itr = new ListItr(size()); 792 public boolean hasNext() { 793 return itr.hasPrevious(); 794 } 795 public E next() { 796 return itr.previous(); 797 } 798 public void remove() { 799 itr.remove(); 800 } 801 } 802 803 /** 804 * 调用父类进行链表的克隆 805 * @return 806 */ 807 @SuppressWarnings("unchecked") 808 private LinkedList<E> superClone() { 809 try { 810 return (LinkedList<E>) super.clone(); 811 } catch (CloneNotSupportedException e) { 812 throw new InternalError(e); 813 } 814 } 815 816 /** 817 * 进行链表的克隆 818 */ 819 public Object clone() { 820 LinkedList<E> clone = superClone(); 821 822 // Put clone into "virgin" state 823 clone.first = clone.last = null; 824 clone.size = 0; 825 clone.modCount = 0; 826 827 // Initialize clone with our elements 828 for (Node<E> x = first; x != null; x = x.next) 829 clone.add(x.item); 830 831 return clone; 832 } 833 834 /** 835 * 将链表转换为Object类型的数组 836 */ 837 public Object[] toArray() { 838 Object[] result = new Object[size]; 839 int i = 0; 840 for (Node<E> x = first; x != null; x = x.next) 841 result[i++] = x.item; 842 return result; 843 } 844 845 /** 846 * 将链表转换为指定类型的数组 847 */ 848 @SuppressWarnings("unchecked") 849 public <T> T[] toArray(T[] a) { 850 if (a.length < size) 851 a = (T[])java.lang.reflect.Array.newInstance( 852 a.getClass().getComponentType(), size); 853 int i = 0; 854 Object[] result = a; 855 for (Node<E> x = first; x != null; x = x.next) 856 result[i++] = x.item; 857 858 if (a.length > size) 859 a[size] = null; 860 861 return a; 862 } 863 864 private static final long serialVersionUID = 876323262645176354L; 865 866 /** 867 * 序列化链表中的元素 868 */ 869 private void writeObject(java.io.ObjectOutputStream s) 870 throws java.io.IOException { 871 // Write out any hidden serialization magic 872 s.defaultWriteObject(); 873 874 // Write out size 875 s.writeInt(size); 876 877 // Write out all elements in the proper order. 878 for (Node<E> x = first; x != null; x = x.next) 879 s.writeObject(x.item); 880 } 881 882 /** 883 * 反序列化链表中的元素 884 */ 885 @SuppressWarnings("unchecked") 886 private void readObject(java.io.ObjectInputStream s) 887 throws java.io.IOException, ClassNotFoundException { 888 // Read in any hidden serialization magic 889 s.defaultReadObject(); 890 891 // Read in size 892 int size = s.readInt(); 893 894 // Read in all elements in the proper order. 895 for (int i = 0; i < size; i++) 896 linkLast((E)s.readObject()); 897 } 898 899 /** 900 * java8新增的返回 901 * 返回一个并行的分片迭代器 902 */ 903 @Override 904 public Spliterator<E> spliterator() { 905 return new LLSpliterator<E>(this, -1, 0); 906 } 907 908 /** A customized variant of Spliterators.IteratorSpliterator */ 909 static final class LLSpliterator<E> implements Spliterator<E> { 910 static final int BATCH_UNIT = 1 << 10; // batch array size increment 911 static final int MAX_BATCH = 1 << 25; // max batch array size; 912 final LinkedList<E> list; // null OK unless traversed 913 Node<E> current; // current node; null until initialized 914 int est; // size estimate; -1 until first needed 915 int expectedModCount; // initialized when est set 916 int batch; // batch size for splits 917 918 LLSpliterator(LinkedList<E> list, int est, int expectedModCount) { 919 this.list = list; 920 this.est = est; 921 this.expectedModCount = expectedModCount; 922 } 923 924 final int getEst() { 925 int s; // force initialization 926 final LinkedList<E> lst; 927 if ((s = est) < 0) { 928 if ((lst = list) == null) 929 s = est = 0; 930 else { 931 expectedModCount = lst.modCount; 932 current = lst.first; 933 s = est = lst.size; 934 } 935 } 936 return s; 937 } 938 939 public long estimateSize() { return (long) getEst(); } 940 941 public Spliterator<E> trySplit() { 942 Node<E> p; 943 int s = getEst(); 944 if (s > 1 && (p = current) != null) { 945 int n = batch + BATCH_UNIT; 946 if (n > s) 947 n = s; 948 if (n > MAX_BATCH) 949 n = MAX_BATCH; 950 Object[] a = new Object[n]; 951 int j = 0; 952 do { a[j++] = p.item; } while ((p = p.next) != null && j < n); 953 current = p; 954 batch = j; 955 est = s - j; 956 return Spliterators.spliterator(a, 0, j, Spliterator.ORDERED); 957 } 958 return null; 959 } 960 961 public void forEachRemaining(Consumer<? super E> action) { 962 Node<E> p; int n; 963 if (action == null) throw new NullPointerException(); 964 if ((n = getEst()) > 0 && (p = current) != null) { 965 current = null; 966 est = 0; 967 do { 968 E e = p.item; 969 p = p.next; 970 action.accept(e); 971 } while (p != null && --n > 0); 972 } 973 if (list.modCount != expectedModCount) 974 throw new ConcurrentModificationException(); 975 } 976 977 public boolean tryAdvance(Consumer<? super E> action) { 978 Node<E> p; 979 if (action == null) throw new NullPointerException(); 980 if (getEst() > 0 && (p = current) != null) { 981 --est; 982 E e = p.item; 983 current = p.next; 984 action.accept(e); 985 if (list.modCount != expectedModCount) 986 throw new ConcurrentModificationException(); 987 return true; 988 } 989 return false; 990 } 991 992 public int characteristics() { 993 return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED; 994 } 995 } 996 997 }
标签:== 堆栈 tee author ast 反序 iter tin 克隆
原文地址:http://www.cnblogs.com/beliefes/p/7471038.html