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