001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * https://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.collections4.list; 018 019import java.io.IOException; 020import java.io.ObjectInputStream; 021import java.io.ObjectOutputStream; 022import java.lang.reflect.Array; 023import java.util.AbstractList; 024import java.util.Collection; 025import java.util.ConcurrentModificationException; 026import java.util.Iterator; 027import java.util.List; 028import java.util.ListIterator; 029import java.util.NoSuchElementException; 030import java.util.Objects; 031 032import org.apache.commons.collections4.CollectionUtils; 033import org.apache.commons.collections4.OrderedIterator; 034 035/** 036 * An abstract implementation of a linked list which provides numerous points for 037 * subclasses to override. 038 * <p> 039 * Overridable methods are provided to change the storage node and to change how 040 * nodes are added to and removed. Hopefully, all you need for unusual subclasses 041 * is here. 042 * </p> 043 * <p> 044 * This is a copy of AbstractLinkedList, modified to be compatible with Java 21 045 * (see COLLECTIONS-842 for details). 046 * </p> 047 * 048 * @param <E> The type of elements in this list 049 * @see AbstractLinkedList 050 * @since 4.5.0-M3 051 */ 052public abstract class AbstractLinkedListJava21<E> implements List<E> { 053 054 /* 055 * Implementation notes: 056 * - a standard circular doubly-linked list 057 * - a marker node is stored to mark the start and the end of the list 058 * - node creation and removal always occurs through createNode() and 059 * removeNode(). 060 * - a modification count is kept, with the same semantics as 061 * {@link java.util.LinkedList}. 062 * - respects {@link AbstractList#modCount} 063 */ 064 065 /** 066 * A list iterator over the linked list. 067 * 068 * @param <E> The type of elements in this iterator. 069 */ 070 protected static class LinkedListIterator<E> implements ListIterator<E>, OrderedIterator<E> { 071 072 /** The parent list */ 073 protected final AbstractLinkedListJava21<E> parent; 074 075 /** 076 * The node that will be returned by {@link #next()}. If this is equal 077 * to {@link AbstractLinkedListJava21#header} then there are no more values to return. 078 */ 079 protected Node<E> next; 080 081 /** 082 * The index of {@link #next}. 083 */ 084 protected int nextIndex; 085 086 /** 087 * The last node that was returned by {@link #next()} or {@link 088 * #previous()}. Set to {@code null} if {@link #next()} or {@link 089 * #previous()} haven't been called, or if the node has been removed 090 * with {@link #remove()} or a new node added with {@link #add(Object)}. 091 * Should be accessed through {@link #getLastNodeReturned()} to enforce 092 * this behavior. 093 */ 094 protected Node<E> current; 095 096 /** 097 * The modification count that the list is expected to have. If the list 098 * doesn't have this count, then a 099 * {@link ConcurrentModificationException} may be thrown by 100 * the operations. 101 */ 102 protected int expectedModCount; 103 104 /** 105 * Create a ListIterator for a list. 106 * 107 * @param parent The parent list 108 * @param fromIndex The index to start at 109 * @throws IndexOutOfBoundsException if fromIndex is less than 0 or greater than the size of the list 110 */ 111 protected LinkedListIterator(final AbstractLinkedListJava21<E> parent, final int fromIndex) 112 throws IndexOutOfBoundsException { 113 this.parent = parent; 114 this.expectedModCount = parent.modCount; 115 this.next = parent.getNode(fromIndex, true); 116 this.nextIndex = fromIndex; 117 } 118 119 @Override 120 public void add(final E obj) { 121 checkModCount(); 122 parent.addNodeBefore(next, obj); 123 current = null; 124 nextIndex++; 125 expectedModCount++; 126 } 127 128 /** 129 * Checks the modification count of the list is the value that this 130 * object expects. 131 * 132 * @throws ConcurrentModificationException If the list's modification 133 * count isn't the value that was expected. 134 */ 135 protected void checkModCount() { 136 if (parent.modCount != expectedModCount) { 137 throw new ConcurrentModificationException(); 138 } 139 } 140 141 /** 142 * Gets the last node returned. 143 * 144 * @return The last node returned 145 * @throws IllegalStateException If {@link #next()} or {@link #previous()} haven't been called, 146 * or if the node has been removed with {@link #remove()} or a new node added with {@link #add(Object)}. 147 */ 148 protected Node<E> getLastNodeReturned() throws IllegalStateException { 149 if (current == null) { 150 throw new IllegalStateException(); 151 } 152 return current; 153 } 154 155 @Override 156 public boolean hasNext() { 157 return next != parent.header; 158 } 159 160 @Override 161 public boolean hasPrevious() { 162 return next.previous != parent.header; 163 } 164 165 @Override 166 public E next() { 167 checkModCount(); 168 if (!hasNext()) { 169 throw new NoSuchElementException("No element at index " + nextIndex + "."); 170 } 171 final E value = next.getValue(); 172 current = next; 173 next = next.next; 174 nextIndex++; 175 return value; 176 } 177 178 @Override 179 public int nextIndex() { 180 return nextIndex; 181 } 182 183 @Override 184 public E previous() { 185 checkModCount(); 186 if (!hasPrevious()) { 187 throw new NoSuchElementException("Already at start of list."); 188 } 189 next = next.previous; 190 final E value = next.getValue(); 191 current = next; 192 nextIndex--; 193 return value; 194 } 195 196 @Override 197 public int previousIndex() { 198 // not normally overridden, as relative to nextIndex() 199 return nextIndex() - 1; 200 } 201 202 @Override 203 public void remove() { 204 checkModCount(); 205 if (current == next) { 206 // remove() following previous() 207 next = next.next; 208 parent.removeNode(getLastNodeReturned()); 209 } else { 210 // remove() following next() 211 parent.removeNode(getLastNodeReturned()); 212 nextIndex--; 213 } 214 current = null; 215 expectedModCount++; 216 } 217 218 @Override 219 public void set(final E obj) { 220 checkModCount(); 221 getLastNodeReturned().setValue(obj); 222 } 223 224 } 225 226 /** 227 * The sublist implementation for AbstractLinkedListJava21. 228 * 229 * @param <E> The type of elements in this list. 230 */ 231 protected static class LinkedSubList<E> extends AbstractList<E> { 232 233 /** The main list */ 234 AbstractLinkedListJava21<E> parent; 235 236 /** Offset from the main list */ 237 int offset; 238 239 /** Sublist size */ 240 int size; 241 242 /** Sublist modCount */ 243 int expectedModCount; 244 245 /** 246 * Constructs a new instance. 247 * 248 * @param parent The parent AbstractLinkedList. 249 * @param fromIndex An index greater or equal to 0 and less than {@code toIndex}. 250 * @param toIndex An index greater than {@code fromIndex}. 251 */ 252 protected LinkedSubList(final AbstractLinkedListJava21<E> parent, final int fromIndex, final int toIndex) { 253 if (fromIndex < 0) { 254 throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); 255 } 256 if (toIndex > parent.size()) { 257 throw new IndexOutOfBoundsException("toIndex = " + toIndex); 258 } 259 if (fromIndex > toIndex) { 260 throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); 261 } 262 this.parent = parent; 263 this.offset = fromIndex; 264 this.size = toIndex - fromIndex; 265 this.expectedModCount = parent.modCount; 266 } 267 268 @Override 269 public void add(final int index, final E obj) { 270 rangeCheck(index, size + 1); 271 checkModCount(); 272 parent.add(index + offset, obj); 273 expectedModCount = parent.modCount; 274 size++; 275 modCount++; 276 } 277 278 @Override 279 public boolean addAll(final Collection<? extends E> coll) { 280 return addAll(size, coll); 281 } 282 283 @Override 284 public boolean addAll(final int index, final Collection<? extends E> coll) { 285 rangeCheck(index, size + 1); 286 final int cSize = coll.size(); 287 if (cSize == 0) { 288 return false; 289 } 290 291 checkModCount(); 292 parent.addAll(offset + index, coll); 293 expectedModCount = parent.modCount; 294 size += cSize; 295 modCount++; 296 return true; 297 } 298 299 /** 300 * Throws a {@link ConcurrentModificationException} if this instance fails its concurrency check. 301 */ 302 protected void checkModCount() { 303 if (parent.modCount != expectedModCount) { 304 throw new ConcurrentModificationException(); 305 } 306 } 307 308 @Override 309 public void clear() { 310 checkModCount(); 311 final Iterator<E> it = iterator(); 312 while (it.hasNext()) { 313 it.next(); 314 it.remove(); 315 } 316 } 317 318 @Override 319 public E get(final int index) { 320 rangeCheck(index, size); 321 checkModCount(); 322 return parent.get(index + offset); 323 } 324 325 @Override 326 public Iterator<E> iterator() { 327 checkModCount(); 328 return parent.createSubListIterator(this); 329 } 330 331 @Override 332 public ListIterator<E> listIterator(final int index) { 333 rangeCheck(index, size + 1); 334 checkModCount(); 335 return parent.createSubListListIterator(this, index); 336 } 337 338 /** 339 * Throws an {@link IndexOutOfBoundsException} if the given indices are out of bounds. 340 * 341 * @param index lower index. 342 * @param beyond upper index. 343 */ 344 protected void rangeCheck(final int index, final int beyond) { 345 if (index < 0 || index >= beyond) { 346 throw new IndexOutOfBoundsException("Index '" + index + "' out of bounds for size '" + size + "'"); 347 } 348 } 349 350 @Override 351 public E remove(final int index) { 352 rangeCheck(index, size); 353 checkModCount(); 354 final E result = parent.remove(index + offset); 355 expectedModCount = parent.modCount; 356 size--; 357 modCount++; 358 return result; 359 } 360 361 @Override 362 public E set(final int index, final E obj) { 363 rangeCheck(index, size); 364 checkModCount(); 365 return parent.set(index + offset, obj); 366 } 367 368 @Override 369 public int size() { 370 checkModCount(); 371 return size; 372 } 373 374 @Override 375 public List<E> subList(final int fromIndexInclusive, final int toIndexExclusive) { 376 return new LinkedSubList<>(parent, fromIndexInclusive + offset, toIndexExclusive + offset); 377 } 378 } 379 380 /** 381 * A list iterator over the linked sub list. 382 * 383 * @param <E> The type of elements in this iterator. 384 */ 385 protected static class LinkedSubListIterator<E> extends LinkedListIterator<E> { 386 387 /** The sub list */ 388 protected final LinkedSubList<E> sub; 389 390 /** 391 * Constructs a new instance. 392 * 393 * @param sub The sub-list. 394 * @param startIndex The starting index. 395 */ 396 protected LinkedSubListIterator(final LinkedSubList<E> sub, final int startIndex) { 397 super(sub.parent, startIndex + sub.offset); 398 this.sub = sub; 399 } 400 401 @Override 402 public void add(final E obj) { 403 super.add(obj); 404 sub.expectedModCount = parent.modCount; 405 sub.size++; 406 } 407 408 @Override 409 public boolean hasNext() { 410 return nextIndex() < sub.size; 411 } 412 413 @Override 414 public boolean hasPrevious() { 415 return previousIndex() >= 0; 416 } 417 418 @Override 419 public int nextIndex() { 420 return super.nextIndex() - sub.offset; 421 } 422 423 @Override 424 public void remove() { 425 super.remove(); 426 sub.expectedModCount = parent.modCount; 427 sub.size--; 428 } 429 } 430 431 /** 432 * A node within the linked list. 433 * <p> 434 * From Commons Collections 3.1, all access to the {@code value} property 435 * is via the methods on this class. 436 * </p> 437 * 438 * @param <E> The type of the node value. 439 */ 440 protected static class Node<E> { 441 442 /** A pointer to the node before this node */ 443 protected Node<E> previous; 444 445 /** A pointer to the node after this node */ 446 protected Node<E> next; 447 448 /** The object contained within this node */ 449 protected E value; 450 451 /** 452 * Constructs a new header node. 453 */ 454 protected Node() { 455 previous = this; 456 next = this; 457 } 458 459 /** 460 * Constructs a new node. 461 * 462 * @param value The value to store 463 */ 464 protected Node(final E value) { 465 this.value = value; 466 } 467 468 /** 469 * Constructs a new node. 470 * 471 * @param previous The previous node in the list 472 * @param next The next node in the list 473 * @param value The value to store 474 */ 475 protected Node(final Node<E> previous, final Node<E> next, final E value) { 476 this.previous = previous; 477 this.next = next; 478 this.value = value; 479 } 480 481 /** 482 * Gets the next node. 483 * 484 * @return The next node 485 * @since 3.1 486 */ 487 protected Node<E> getNextNode() { 488 return next; 489 } 490 491 /** 492 * Gets the previous node. 493 * 494 * @return The previous node 495 * @since 3.1 496 */ 497 protected Node<E> getPreviousNode() { 498 return previous; 499 } 500 501 /** 502 * Gets the value of the node. 503 * 504 * @return The value 505 * @since 3.1 506 */ 507 protected E getValue() { 508 return value; 509 } 510 511 /** 512 * Sets the next node. 513 * 514 * @param next The next node 515 * @since 3.1 516 */ 517 protected void setNextNode(final Node<E> next) { 518 this.next = next; 519 } 520 521 /** 522 * Sets the previous node. 523 * 524 * @param previous The previous node 525 * @since 3.1 526 */ 527 protected void setPreviousNode(final Node<E> previous) { 528 this.previous = previous; 529 } 530 531 /** 532 * Sets the value of the node. 533 * 534 * @param value The value 535 * @since 3.1 536 */ 537 protected void setValue(final E value) { 538 this.value = value; 539 } 540 } 541 542 /** 543 * A {@link Node} which indicates the start and end of the list and does not 544 * hold a value. The value of {@code next} is the first item in the 545 * list. The value of {@code previous} is the last item in the list. 546 */ 547 transient Node<E> header; 548 549 /** The size of the list */ 550 transient int size; 551 552 /** Modification count for iterators */ 553 transient int modCount; 554 555 /** 556 * Constructor that does nothing (intended for deserialization). 557 * <p> 558 * If this constructor is used by a serializable subclass then the init() 559 * method must be called. 560 * </p> 561 */ 562 protected AbstractLinkedListJava21() { 563 } 564 565 /** 566 * Constructs a list copying data from the specified collection. 567 * 568 * @param coll The collection to copy 569 */ 570 protected AbstractLinkedListJava21(final Collection<? extends E> coll) { 571 init(); 572 addAll(coll); 573 } 574 575 @Override 576 public boolean add(final E value) { 577 addLast(value); 578 return true; 579 } 580 581 @Override 582 public void add(final int index, final E value) { 583 final Node<E> node = getNode(index, true); 584 addNodeBefore(node, value); 585 } 586 587 @Override 588 public boolean addAll(final Collection<? extends E> coll) { 589 return addAll(size, coll); 590 } 591 592 @Override 593 public boolean addAll(final int index, final Collection<? extends E> coll) { 594 final Node<E> node = getNode(index, true); 595 for (final E e : coll) { 596 addNodeBefore(node, e); 597 } 598 return true; 599 } 600 601 /** 602 * {@inheritDoc} 603 */ 604 public void addFirst(final E o) { 605 addNodeAfter(header, o); 606 } 607 608 /** 609 * {@inheritDoc} 610 */ 611 public void addLast(final E o) { 612 addNodeBefore(header, o); 613 } 614 615 /** 616 * Inserts a new node into the list. 617 * 618 * @param nodeToInsert new node to insert 619 * @param insertBeforeNode node to insert before 620 * @throws NullPointerException if either node is null 621 */ 622 protected void addNode(final Node<E> nodeToInsert, final Node<E> insertBeforeNode) { 623 Objects.requireNonNull(nodeToInsert, "nodeToInsert"); 624 Objects.requireNonNull(insertBeforeNode, "insertBeforeNode"); 625 nodeToInsert.next = insertBeforeNode; 626 nodeToInsert.previous = insertBeforeNode.previous; 627 insertBeforeNode.previous.next = nodeToInsert; 628 insertBeforeNode.previous = nodeToInsert; 629 size++; 630 modCount++; 631 } 632 633 /** 634 * Creates a new node with the specified object as its 635 * {@code value} and inserts it after {@code node}. 636 * <p> 637 * This implementation uses {@link #createNode(Object)} and 638 * {@link #addNode(AbstractLinkedListJava21.Node,AbstractLinkedListJava21.Node)}. 639 * </p> 640 * 641 * @param node node to insert after 642 * @param value value of the newly added node 643 * @throws NullPointerException if {@code node} is null 644 */ 645 protected void addNodeAfter(final Node<E> node, final E value) { 646 final Node<E> newNode = createNode(value); 647 addNode(newNode, node.next); 648 } 649 650 /** 651 * Creates a new node with the specified object as its 652 * {@code value} and inserts it before {@code node}. 653 * <p> 654 * This implementation uses {@link #createNode(Object)} and 655 * {@link #addNode(AbstractLinkedListJava21.Node,AbstractLinkedListJava21.Node)}. 656 * </p> 657 * 658 * @param node node to insert before 659 * @param value value of the newly added node 660 * @throws NullPointerException if {@code node} is null 661 */ 662 protected void addNodeBefore(final Node<E> node, final E value) { 663 final Node<E> newNode = createNode(value); 664 addNode(newNode, node); 665 } 666 667 @Override 668 public void clear() { 669 removeAllNodes(); 670 } 671 672 @Override 673 public boolean contains(final Object value) { 674 return indexOf(value) != -1; 675 } 676 677 @Override 678 public boolean containsAll(final Collection<?> coll) { 679 for (final Object o : coll) { 680 if (!contains(o)) { 681 return false; 682 } 683 } 684 return true; 685 } 686 687 /** 688 * Creates a new node with previous, next and element all set to null. 689 * This implementation creates a new empty Node. 690 * Subclasses can override this to create a different class. 691 * 692 * @return newly created node 693 */ 694 protected Node<E> createHeaderNode() { 695 return new Node<>(); 696 } 697 698 /** 699 * Creates a new node with the specified properties. 700 * This implementation creates a new Node with data. 701 * Subclasses can override this to create a different class. 702 * 703 * @param value value of the new node 704 * @return A new node containing the value 705 */ 706 protected Node<E> createNode(final E value) { 707 return new Node<>(value); 708 } 709 710 /** 711 * Creates an iterator for the sublist. 712 * 713 * @param subList The sublist to get an iterator for 714 * @return A new iterator on the given sublist 715 */ 716 protected Iterator<E> createSubListIterator(final LinkedSubList<E> subList) { 717 return createSubListListIterator(subList, 0); 718 } 719 720 /** 721 * Creates a list iterator for the sublist. 722 * 723 * @param subList The sublist to get an iterator for 724 * @param fromIndex The index to start from, relative to the sublist 725 * @return A new list iterator on the given sublist 726 */ 727 protected ListIterator<E> createSubListListIterator(final LinkedSubList<E> subList, final int fromIndex) { 728 return new LinkedSubListIterator<>(subList, fromIndex); 729 } 730 731 /** 732 * Deserializes the data held in this object to the stream specified. 733 * <p> 734 * The first serializable subclass must call this method from 735 * {@code readObject}. 736 * </p> 737 * 738 * @param inputStream The stream to read the object from 739 * @throws IOException if any error occurs while reading from the stream 740 * @throws ClassNotFoundException if a class read from the stream cannot be loaded 741 */ 742 @SuppressWarnings("unchecked") 743 protected void doReadObject(final ObjectInputStream inputStream) throws IOException, ClassNotFoundException { 744 init(); 745 final int size = inputStream.readInt(); 746 for (int i = 0; i < size; i++) { 747 add((E) inputStream.readObject()); 748 } 749 } 750 751 /** 752 * Serializes the data held in this object to the stream specified. 753 * <p> 754 * The first serializable subclass must call this method from 755 * {@code writeObject}. 756 * </p> 757 * 758 * @param outputStream The stream to write the object to 759 * @throws IOException if anything goes wrong 760 */ 761 protected void doWriteObject(final ObjectOutputStream outputStream) throws IOException { 762 // Write the size so we know how many nodes to read back 763 outputStream.writeInt(size()); 764 for (final E e : this) { 765 outputStream.writeObject(e); 766 } 767 } 768 769 @Override 770 public boolean equals(final Object obj) { 771 if (obj == this) { 772 return true; 773 } 774 if (!(obj instanceof List)) { 775 return false; 776 } 777 final List<?> other = (List<?>) obj; 778 if (other.size() != size()) { 779 return false; 780 } 781 final ListIterator<?> it1 = listIterator(); 782 final ListIterator<?> it2 = other.listIterator(); 783 while (it1.hasNext() && it2.hasNext()) { 784 if (!Objects.equals(it1.next(), it2.next())) { 785 return false; 786 } 787 } 788 return !(it1.hasNext() || it2.hasNext()); 789 } 790 791 @Override 792 public E get(final int index) { 793 final Node<E> node = getNode(index, false); 794 return node.getValue(); 795 } 796 797 /** 798 * {@inheritDoc} 799 */ 800 public E getFirst() { 801 final Node<E> node = header.next; 802 if (node == header) { 803 throw new NoSuchElementException(); 804 } 805 return node.getValue(); 806 } 807 808 /** 809 * {@inheritDoc} 810 */ 811 public E getLast() { 812 final Node<E> node = header.previous; 813 if (node == header) { 814 throw new NoSuchElementException(); 815 } 816 return node.getValue(); 817 } 818 819 /** 820 * Gets the node at a particular index. 821 * 822 * @param index The index, starting from 0 823 * @param endMarkerAllowed whether or not the end marker can be returned if 824 * startIndex is set to the list's size 825 * @return The node at the given index 826 * @throws IndexOutOfBoundsException if the index is less than 0; equal to 827 * the size of the list and endMakerAllowed is false; or greater than the 828 * size of the list 829 */ 830 protected Node<E> getNode(final int index, final boolean endMarkerAllowed) throws IndexOutOfBoundsException { 831 // Check the index is within the bounds 832 if (index < 0) { 833 throw new IndexOutOfBoundsException("Couldn't get the node: " + 834 "index (" + index + ") less than zero."); 835 } 836 if (!endMarkerAllowed && index == size) { 837 throw new IndexOutOfBoundsException("Couldn't get the node: " + 838 "index (" + index + ") is the size of the list."); 839 } 840 if (index > size) { 841 throw new IndexOutOfBoundsException("Couldn't get the node: " + 842 "index (" + index + ") greater than the size of the " + 843 "list (" + size + ")."); 844 } 845 // Search the list and get the node 846 Node<E> node; 847 if (index < size / 2) { 848 // Search forwards 849 node = header.next; 850 for (int currentIndex = 0; currentIndex < index; currentIndex++) { 851 node = node.next; 852 } 853 } else { 854 // Search backwards 855 node = header; 856 for (int currentIndex = size; currentIndex > index; currentIndex--) { 857 node = node.previous; 858 } 859 } 860 return node; 861 } 862 863 @Override 864 public int hashCode() { 865 int hashCode = 1; 866 for (final E e : this) { 867 hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode()); 868 } 869 return hashCode; 870 } 871 872 @Override 873 public int indexOf(final Object value) { 874 int i = 0; 875 for (Node<E> node = header.next; node != header; node = node.next) { 876 if (isEqualValue(node.getValue(), value)) { 877 return i; 878 } 879 i++; 880 } 881 return CollectionUtils.INDEX_NOT_FOUND; 882 } 883 884 /** 885 * The equivalent of a default constructor, broken out so it can be called 886 * by any constructor and by {@code readObject}. 887 * Subclasses which override this method should make sure they call super, 888 * so the list is initialized properly. 889 */ 890 protected void init() { 891 header = createHeaderNode(); 892 } 893 894 @Override 895 public boolean isEmpty() { 896 return size() == 0; 897 } 898 899 /** 900 * Compares two values for equals. 901 * This implementation uses the equals method. 902 * Subclasses can override this to match differently. 903 * 904 * @param value1 The first value to compare, may be null 905 * @param value2 The second value to compare, may be null 906 * @return true if equal 907 */ 908 protected boolean isEqualValue(final Object value1, final Object value2) { 909 return Objects.equals(value1, value2); 910 } 911 912 @Override 913 public Iterator<E> iterator() { 914 return listIterator(); 915 } 916 917 @Override 918 public int lastIndexOf(final Object value) { 919 int i = size - 1; 920 for (Node<E> node = header.previous; node != header; node = node.previous) { 921 if (isEqualValue(node.getValue(), value)) { 922 return i; 923 } 924 i--; 925 } 926 return CollectionUtils.INDEX_NOT_FOUND; 927 } 928 929 @Override 930 public ListIterator<E> listIterator() { 931 return new LinkedListIterator<>(this, 0); 932 } 933 934 @Override 935 public ListIterator<E> listIterator(final int fromIndex) { 936 return new LinkedListIterator<>(this, fromIndex); 937 } 938 939 @Override 940 public E remove(final int index) { 941 final Node<E> node = getNode(index, false); 942 final E oldValue = node.getValue(); 943 removeNode(node); 944 return oldValue; 945 } 946 947 @Override 948 public boolean remove(final Object value) { 949 for (Node<E> node = header.next; node != header; node = node.next) { 950 if (isEqualValue(node.getValue(), value)) { 951 removeNode(node); 952 return true; 953 } 954 } 955 return false; 956 } 957 958 /** 959 * {@inheritDoc} 960 * <p> 961 * This implementation iterates over the elements of this list, checking each element in 962 * turn to see if it's contained in {@code coll}. If it's contained, it's removed 963 * from this list. As a consequence, it is advised to use a collection type for 964 * {@code coll} that provides a fast (for example O(1)) implementation of 965 * {@link Collection#contains(Object)}. 966 * </p> 967 */ 968 @Override 969 public boolean removeAll(final Collection<?> coll) { 970 boolean modified = false; 971 final Iterator<E> it = iterator(); 972 while (it.hasNext()) { 973 if (coll.contains(it.next())) { 974 it.remove(); 975 modified = true; 976 } 977 } 978 return modified; 979 } 980 981 /** 982 * Removes all nodes by resetting the circular list marker. 983 */ 984 protected void removeAllNodes() { 985 header.next = header; 986 header.previous = header; 987 size = 0; 988 modCount++; 989 } 990 991 /** 992 * {@inheritDoc} 993 */ 994 public E removeFirst() { 995 final Node<E> node = header.next; 996 if (node == header) { 997 throw new NoSuchElementException(); 998 } 999 final E oldValue = node.getValue(); 1000 removeNode(node); 1001 return oldValue; 1002 } 1003 1004 /** 1005 * {@inheritDoc} 1006 */ 1007 public E removeLast() { 1008 final Node<E> node = header.previous; 1009 if (node == header) { 1010 throw new NoSuchElementException(); 1011 } 1012 final E oldValue = node.getValue(); 1013 removeNode(node); 1014 return oldValue; 1015 } 1016 1017 /** 1018 * Removes the specified node from the list. 1019 * 1020 * @param node The node to remove 1021 * @throws NullPointerException if {@code node} is null 1022 */ 1023 protected void removeNode(final Node<E> node) { 1024 Objects.requireNonNull(node, "node"); 1025 node.previous.next = node.next; 1026 node.next.previous = node.previous; 1027 size--; 1028 modCount++; 1029 } 1030 1031 /** 1032 * {@inheritDoc} 1033 * <p> 1034 * This implementation iterates over the elements of this list, checking each element in 1035 * turn to see if it's contained in {@code coll}. If it's not contained, it's removed 1036 * from this list. As a consequence, it is advised to use a collection type for 1037 * {@code coll} that provides a fast (for example O(1)) implementation of 1038 * {@link Collection#contains(Object)}. 1039 * </p> 1040 */ 1041 @Override 1042 public boolean retainAll(final Collection<?> coll) { 1043 boolean modified = false; 1044 final Iterator<E> it = iterator(); 1045 while (it.hasNext()) { 1046 if (!coll.contains(it.next())) { 1047 it.remove(); 1048 modified = true; 1049 } 1050 } 1051 return modified; 1052 } 1053 1054 @Override 1055 public E set(final int index, final E value) { 1056 final Node<E> node = getNode(index, false); 1057 final E oldValue = node.getValue(); 1058 updateNode(node, value); 1059 return oldValue; 1060 } 1061 1062 @Override 1063 public int size() { 1064 return size; 1065 } 1066 1067 /** 1068 * Gets a sublist of the main list. 1069 * 1070 * @param fromIndexInclusive The index to start from 1071 * @param toIndexExclusive The index to end at 1072 * @return The new sublist 1073 */ 1074 @Override 1075 public List<E> subList(final int fromIndexInclusive, final int toIndexExclusive) { 1076 return new LinkedSubList<>(this, fromIndexInclusive, toIndexExclusive); 1077 } 1078 1079 @Override 1080 public Object[] toArray() { 1081 return toArray(new Object[size]); 1082 } 1083 1084 @Override 1085 @SuppressWarnings("unchecked") 1086 public <T> T[] toArray(T[] array) { 1087 // Extend the array if needed 1088 if (array.length < size) { 1089 final Class<?> componentType = array.getClass().getComponentType(); 1090 array = (T[]) Array.newInstance(componentType, size); 1091 } 1092 // Copy the values into the array 1093 int i = 0; 1094 for (Node<E> node = header.next; node != header; node = node.next, i++) { 1095 array[i] = (T) node.getValue(); 1096 } 1097 // Set the value after the last value to null 1098 if (array.length > size) { 1099 array[size] = null; 1100 } 1101 return array; 1102 } 1103 1104 @Override 1105 public String toString() { 1106 if (isEmpty()) { 1107 return "[]"; 1108 } 1109 final StringBuilder buf = new StringBuilder(16 * size()); 1110 buf.append(CollectionUtils.DEFAULT_TOSTRING_PREFIX); 1111 1112 final Iterator<E> it = iterator(); 1113 boolean hasNext = it.hasNext(); 1114 while (hasNext) { 1115 final Object value = it.next(); 1116 buf.append(value == this ? "(this Collection)" : value); 1117 hasNext = it.hasNext(); 1118 if (hasNext) { 1119 buf.append(", "); 1120 } 1121 } 1122 buf.append(CollectionUtils.DEFAULT_TOSTRING_SUFFIX); 1123 return buf.toString(); 1124 } 1125 1126 /** 1127 * Updates the node with a new value. 1128 * This implementation sets the value on the node. 1129 * Subclasses can override this to record the change. 1130 * 1131 * @param node node to update 1132 * @param value new value of the node 1133 */ 1134 protected void updateNode(final Node<E> node, final E value) { 1135 node.setValue(value); 1136 } 1137 1138}