View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4.list;
18  
19  import java.io.IOException;
20  import java.io.ObjectInputStream;
21  import java.io.ObjectOutputStream;
22  import java.lang.reflect.Array;
23  import java.util.AbstractList;
24  import java.util.Collection;
25  import java.util.ConcurrentModificationException;
26  import java.util.Iterator;
27  import java.util.List;
28  import java.util.ListIterator;
29  import java.util.NoSuchElementException;
30  import java.util.Objects;
31  
32  import org.apache.commons.collections4.CollectionUtils;
33  import org.apache.commons.collections4.OrderedIterator;
34  
35  /**
36   * An abstract implementation of a linked list which provides numerous points for
37   * subclasses to override.
38   * <p>
39   * Overridable methods are provided to change the storage node and to change how
40   * nodes are added to and removed. Hopefully, all you need for unusual subclasses
41   * is here.
42   * </p>
43   * <p>
44   * This is a copy of AbstractLinkedList, modified to be compatible with Java 21
45   * (see COLLECTIONS-842 for details).
46   * </p>
47   *
48   * @param <E> The type of elements in this list
49   * @see AbstractLinkedList
50   * @since 4.5.0-M3
51   */
52  public abstract class AbstractLinkedListJava21<E> implements List<E> {
53  
54      /*
55       * Implementation notes:
56       * - a standard circular doubly-linked list
57       * - a marker node is stored to mark the start and the end of the list
58       * - node creation and removal always occurs through createNode() and
59       *   removeNode().
60       * - a modification count is kept, with the same semantics as
61       * {@link java.util.LinkedList}.
62       * - respects {@link AbstractList#modCount}
63       */
64  
65      /**
66       * A list iterator over the linked list.
67       *
68       * @param <E> The type of elements in this iterator.
69       */
70      protected static class LinkedListIterator<E> implements ListIterator<E>, OrderedIterator<E> {
71  
72          /** The parent list */
73          protected final AbstractLinkedListJava21<E> parent;
74  
75          /**
76           * The node that will be returned by {@link #next()}. If this is equal
77           * to {@link AbstractLinkedListJava21#header} then there are no more values to return.
78           */
79          protected Node<E> next;
80  
81          /**
82           * The index of {@link #next}.
83           */
84          protected int nextIndex;
85  
86          /**
87           * The last node that was returned by {@link #next()} or {@link
88           * #previous()}. Set to {@code null} if {@link #next()} or {@link
89           * #previous()} haven't been called, or if the node has been removed
90           * with {@link #remove()} or a new node added with {@link #add(Object)}.
91           * Should be accessed through {@link #getLastNodeReturned()} to enforce
92           * this behavior.
93           */
94          protected Node<E> current;
95  
96          /**
97           * The modification count that the list is expected to have. If the list
98           * doesn't have this count, then a
99           * {@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 }