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   *
44   * @param <E> The type of elements in this list
45   * @since 3.0
46   * @deprecated Use {@link AbstractLinkedListJava21} instead
47   */
48  @Deprecated
49  public abstract class AbstractLinkedList<E> implements List<E> {
50  
51      /*
52       * Implementation notes:
53       * - a standard circular doubly-linked list
54       * - a marker node is stored to mark the start and the end of the list
55       * - node creation and removal always occurs through createNode() and
56       *   removeNode().
57       * - a modification count is kept, with the same semantics as
58       * {@link java.util.LinkedList}.
59       * - respects {@link AbstractList#modCount}
60       */
61  
62      /**
63       * A list iterator over the linked list.
64       *
65       * @param <E> The type of elements in this iterator.
66       */
67      protected static class LinkedListIterator<E> implements ListIterator<E>, OrderedIterator<E> {
68  
69          /** The parent list */
70          protected final AbstractLinkedList<E> parent;
71  
72          /**
73           * The node that will be returned by {@link #next()}. If this is equal
74           * to {@link AbstractLinkedList#header} then there are no more values to return.
75           */
76          protected Node<E> next;
77  
78          /**
79           * The index of {@link #next}.
80           */
81          protected int nextIndex;
82  
83          /**
84           * The last node that was returned by {@link #next()} or {@link
85           * #previous()}. Set to {@code null} if {@link #next()} or {@link
86           * #previous()} haven't been called, or if the node has been removed
87           * with {@link #remove()} or a new node added with {@link #add(Object)}.
88           * Should be accessed through {@link #getLastNodeReturned()} to enforce
89           * this behavior.
90           */
91          protected Node<E> current;
92  
93          /**
94           * The modification count that the list is expected to have. If the list
95           * doesn't have this count, then a
96           * {@link ConcurrentModificationException} may be thrown by
97           * the operations.
98           */
99          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 
442         /** A pointer to the node after this node */
443         protected Node<E> next;
444 
445         /** The object contained within this node */
446         protected E value;
447 
448         /**
449          * Constructs a new header node.
450          */
451         protected Node() {
452             previous = this;
453             next = this;
454         }
455 
456         /**
457          * Constructs a new node.
458          *
459          * @param value  The value to store
460          */
461         protected Node(final E value) {
462             this.value = value;
463         }
464 
465         /**
466          * Constructs a new node.
467          *
468          * @param previous  The previous node in the list
469          * @param next  The next node in the list
470          * @param value  The value to store
471          */
472         protected Node(final Node<E> previous, final Node<E> next, final E value) {
473             this.previous = previous;
474             this.next = next;
475             this.value = value;
476         }
477 
478         /**
479          * Gets the next node.
480          *
481          * @return The next node
482          * @since 3.1
483          */
484         protected Node<E> getNextNode() {
485             return next;
486         }
487 
488         /**
489          * Gets the previous node.
490          *
491          * @return The previous node
492          * @since 3.1
493          */
494         protected Node<E> getPreviousNode() {
495             return previous;
496         }
497 
498         /**
499          * Gets the value of the node.
500          *
501          * @return The value
502          * @since 3.1
503          */
504         protected E getValue() {
505             return value;
506         }
507 
508         /**
509          * Sets the next node.
510          *
511          * @param next  The next node
512          * @since 3.1
513          */
514         protected void setNextNode(final Node<E> next) {
515             this.next = next;
516         }
517 
518         /**
519          * Sets the previous node.
520          *
521          * @param previous  The previous node
522          * @since 3.1
523          */
524         protected void setPreviousNode(final Node<E> previous) {
525             this.previous = previous;
526         }
527 
528         /**
529          * Sets the value of the node.
530          *
531          * @param value  The value
532          * @since 3.1
533          */
534         protected void setValue(final E value) {
535             this.value = value;
536         }
537     }
538 
539     /**
540      * A {@link Node} which indicates the start and end of the list and does not
541      * hold a value. The value of {@code next} is the first item in the
542      * list. The value of {@code previous} is the last item in the list.
543      */
544     transient Node<E> header;
545 
546     /** The size of the list */
547     transient int size;
548 
549     /** Modification count for iterators */
550     transient int modCount;
551 
552     /**
553      * Constructor that does nothing (intended for deserialization).
554      * <p>
555      * If this constructor is used by a serializable subclass then the init()
556      * method must be called.
557      */
558     protected AbstractLinkedList() {
559     }
560 
561     /**
562      * Constructs a list copying data from the specified collection.
563      *
564      * @param coll  The collection to copy
565      */
566     protected AbstractLinkedList(final Collection<? extends E> coll) {
567         init();
568         addAll(coll);
569     }
570 
571     @Override
572     public boolean add(final E value) {
573         addLast(value);
574         return true;
575     }
576 
577     @Override
578     public void add(final int index, final E value) {
579         final Node<E> node = getNode(index, true);
580         addNodeBefore(node, value);
581     }
582 
583     @Override
584     public boolean addAll(final Collection<? extends E> coll) {
585         return addAll(size, coll);
586     }
587 
588     @Override
589     public boolean addAll(final int index, final Collection<? extends E> coll) {
590         final Node<E> node = getNode(index, true);
591         for (final E e : coll) {
592             addNodeBefore(node, e);
593         }
594         return true;
595     }
596 
597     /**
598      * Adds an element at the beginning.
599      *
600      * @param e The element to beginning.
601      * @return true.
602      */
603     public boolean addFirst(final E e) {
604         addNodeAfter(header, e);
605         return true;
606     }
607 
608     /**
609      * Adds an element at the end.
610      *
611      * @param e The element to add.
612      * @return true.
613      */
614     public boolean addLast(final E e) {
615         addNodeBefore(header, e);
616         return true;
617     }
618 
619     /**
620      * Inserts a new node into the list.
621      *
622      * @param nodeToInsert  new node to insert
623      * @param insertBeforeNode  node to insert before
624      * @throws NullPointerException if either node is null
625      */
626     protected void addNode(final Node<E> nodeToInsert, final Node<E> insertBeforeNode) {
627         Objects.requireNonNull(nodeToInsert, "nodeToInsert");
628         Objects.requireNonNull(insertBeforeNode, "insertBeforeNode");
629         nodeToInsert.next = insertBeforeNode;
630         nodeToInsert.previous = insertBeforeNode.previous;
631         insertBeforeNode.previous.next = nodeToInsert;
632         insertBeforeNode.previous = nodeToInsert;
633         size++;
634         modCount++;
635     }
636 
637     /**
638      * Creates a new node with the specified object as its
639      * {@code value} and inserts it after {@code node}.
640      * <p>
641      * This implementation uses {@link #createNode(Object)} and
642      * {@link #addNode(AbstractLinkedList.Node,AbstractLinkedList.Node)}.
643      *
644      * @param node  node to insert after
645      * @param value  value of the newly added node
646      * @throws NullPointerException if {@code node} is null
647      */
648     protected void addNodeAfter(final Node<E> node, final E value) {
649         final Node<E> newNode = createNode(value);
650         addNode(newNode, node.next);
651     }
652 
653     /**
654      * Creates a new node with the specified object as its
655      * {@code value} and inserts it before {@code node}.
656      * <p>
657      * This implementation uses {@link #createNode(Object)} and
658      * {@link #addNode(AbstractLinkedList.Node,AbstractLinkedList.Node)}.
659      *
660      * @param node  node to insert before
661      * @param value  value of the newly added node
662      * @throws NullPointerException if {@code node} is null
663      */
664     protected void addNodeBefore(final Node<E> node, final E value) {
665         final Node<E> newNode = createNode(value);
666         addNode(newNode, node);
667     }
668 
669     @Override
670     public void clear() {
671         removeAllNodes();
672     }
673 
674     @Override
675     public boolean contains(final Object value) {
676         return indexOf(value) != -1;
677     }
678 
679     @Override
680     public boolean containsAll(final Collection<?> coll) {
681         for (final Object o : coll) {
682             if (!contains(o)) {
683                 return false;
684             }
685         }
686         return true;
687     }
688 
689     /**
690      * Creates a new node with previous, next and element all set to null.
691      * This implementation creates a new empty Node.
692      * Subclasses can override this to create a different class.
693      *
694      * @return  newly created node
695      */
696     protected Node<E> createHeaderNode() {
697         return new Node<>();
698     }
699 
700     /**
701      * Creates a new node with the specified properties.
702      * This implementation creates a new Node with data.
703      * Subclasses can override this to create a different class.
704      *
705      * @param value  value of the new node
706      * @return A new node containing the value
707      */
708     protected Node<E> createNode(final E value) {
709         return new Node<>(value);
710     }
711 
712     /**
713      * Creates an iterator for the sublist.
714      *
715      * @param subList  The sublist to get an iterator for
716      * @return A new iterator on the given sublist
717      */
718     protected Iterator<E> createSubListIterator(final LinkedSubList<E> subList) {
719         return createSubListListIterator(subList, 0);
720     }
721 
722     /**
723      * Creates a list iterator for the sublist.
724      *
725      * @param subList  The sublist to get an iterator for
726      * @param fromIndex  The index to start from, relative to the sublist
727      * @return A new list iterator on the given sublist
728      */
729     protected ListIterator<E> createSubListListIterator(final LinkedSubList<E> subList, final int fromIndex) {
730         return new LinkedSubListIterator<>(subList, fromIndex);
731     }
732 
733     /**
734      * Deserializes the data held in this object to the stream specified.
735      * <p>
736      * The first serializable subclass must call this method from
737      * {@code readObject}.
738      *
739      * @param inputStream  The stream to read the object from
740      * @throws IOException  if any error occurs while reading from the stream
741      * @throws ClassNotFoundException  if a class read from the stream cannot be loaded
742      */
743     @SuppressWarnings("unchecked")
744     protected void doReadObject(final ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
745         init();
746         final int size = inputStream.readInt();
747         for (int i = 0; i < size; i++) {
748             add((E) inputStream.readObject());
749         }
750     }
751 
752     /**
753      * Serializes the data held in this object to the stream specified.
754      * <p>
755      * The first serializable subclass must call this method from
756      * {@code writeObject}.
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      * Gets the first element.
799      *
800      * @return The first element.
801      */
802     public E getFirst() {
803         final Node<E> node = header.next;
804         if (node == header) {
805             throw new NoSuchElementException();
806         }
807         return node.getValue();
808     }
809 
810     /**
811      * Gets the last element.
812      *
813      * @return The last element.
814      */
815     public E getLast() {
816         final Node<E> node = header.previous;
817         if (node == header) {
818             throw new NoSuchElementException();
819         }
820         return node.getValue();
821     }
822 
823     /**
824      * Gets the node at a particular index.
825      *
826      * @param index  The index, starting from 0
827      * @param endMarkerAllowed  whether or not the end marker can be returned if
828      * startIndex is set to the list's size
829      * @return The node at the given index
830      * @throws IndexOutOfBoundsException if the index is less than 0; equal to
831      * the size of the list and endMakerAllowed is false; or greater than the
832      * size of the list
833      */
834     protected Node<E> getNode(final int index, final boolean endMarkerAllowed) throws IndexOutOfBoundsException {
835         // Check the index is within the bounds
836         if (index < 0) {
837             throw new IndexOutOfBoundsException("Couldn't get the node: " +
838                     "index (" + index + ") less than zero.");
839         }
840         if (!endMarkerAllowed && index == size) {
841             throw new IndexOutOfBoundsException("Couldn't get the node: " +
842                     "index (" + index + ") is the size of the list.");
843         }
844         if (index > size) {
845             throw new IndexOutOfBoundsException("Couldn't get the node: " +
846                     "index (" + index + ") greater than the size of the " +
847                     "list (" + size + ").");
848         }
849         // Search the list and get the node
850         Node<E> node;
851         if (index < size / 2) {
852             // Search forwards
853             node = header.next;
854             for (int currentIndex = 0; currentIndex < index; currentIndex++) {
855                 node = node.next;
856             }
857         } else {
858             // Search backwards
859             node = header;
860             for (int currentIndex = size; currentIndex > index; currentIndex--) {
861                 node = node.previous;
862             }
863         }
864         return node;
865     }
866 
867     @Override
868     public int hashCode() {
869         int hashCode = 1;
870         for (final E e : this) {
871             hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
872         }
873         return hashCode;
874     }
875 
876     @Override
877     public int indexOf(final Object value) {
878         int i = 0;
879         for (Node<E> node = header.next; node != header; node = node.next) {
880             if (isEqualValue(node.getValue(), value)) {
881                 return i;
882             }
883             i++;
884         }
885         return CollectionUtils.INDEX_NOT_FOUND;
886     }
887 
888     /**
889      * The equivalent of a default constructor, broken out so it can be called
890      * by any constructor and by {@code readObject}.
891      * Subclasses which override this method should make sure they call super,
892      * so the list is initialized properly.
893      */
894     protected void init() {
895         header = createHeaderNode();
896     }
897 
898     @Override
899     public boolean isEmpty() {
900         return size() == 0;
901     }
902 
903     /**
904      * Compares two values for equals.
905      * This implementation uses the equals method.
906      * Subclasses can override this to match differently.
907      *
908      * @param value1  The first value to compare, may be null
909      * @param value2  The second value to compare, may be null
910      * @return true if equal
911      */
912     protected boolean isEqualValue(final Object value1, final Object value2) {
913         return Objects.equals(value1, value2);
914     }
915 
916     @Override
917     public Iterator<E> iterator() {
918         return listIterator();
919     }
920 
921     @Override
922     public int lastIndexOf(final Object value) {
923         int i = size - 1;
924         for (Node<E> node = header.previous; node != header; node = node.previous) {
925             if (isEqualValue(node.getValue(), value)) {
926                 return i;
927             }
928             i--;
929         }
930         return CollectionUtils.INDEX_NOT_FOUND;
931     }
932 
933     @Override
934     public ListIterator<E> listIterator() {
935         return new LinkedListIterator<>(this, 0);
936     }
937 
938     @Override
939     public ListIterator<E> listIterator(final int fromIndex) {
940         return new LinkedListIterator<>(this, fromIndex);
941     }
942 
943     @Override
944     public E remove(final int index) {
945         final Node<E> node = getNode(index, false);
946         final E oldValue = node.getValue();
947         removeNode(node);
948         return oldValue;
949     }
950 
951     @Override
952     public boolean remove(final Object value) {
953         for (Node<E> node = header.next; node != header; node = node.next) {
954             if (isEqualValue(node.getValue(), value)) {
955                 removeNode(node);
956                 return true;
957             }
958         }
959         return false;
960     }
961 
962     /**
963      * {@inheritDoc}
964      * <p>
965      * This implementation iterates over the elements of this list, checking each element in
966      * turn to see if it's contained in {@code coll}. If it's contained, it's removed
967      * from this list. As a consequence, it is advised to use a collection type for
968      * {@code coll} that provides a fast (for example O(1)) implementation of
969      * {@link Collection#contains(Object)}.
970      */
971     @Override
972     public boolean removeAll(final Collection<?> coll) {
973         boolean modified = false;
974         final Iterator<E> it = iterator();
975         while (it.hasNext()) {
976             if (coll.contains(it.next())) {
977                 it.remove();
978                 modified = true;
979             }
980         }
981         return modified;
982     }
983 
984     /**
985      * Removes all nodes by resetting the circular list marker.
986      */
987     protected void removeAllNodes() {
988         header.next = header;
989         header.previous = header;
990         size = 0;
991         modCount++;
992     }
993 
994     /**
995      * Removes the first element.
996      *
997      * @return The value removed.
998      */
999     public E removeFirst() {
1000         final Node<E> node = header.next;
1001         if (node == header) {
1002             throw new NoSuchElementException();
1003         }
1004         final E oldValue = node.getValue();
1005         removeNode(node);
1006         return oldValue;
1007     }
1008 
1009     /**
1010      * Removes the last element.
1011      *
1012      * @return The value removed.
1013      */
1014     public E removeLast() {
1015         final Node<E> node = header.previous;
1016         if (node == header) {
1017             throw new NoSuchElementException();
1018         }
1019         final E oldValue = node.getValue();
1020         removeNode(node);
1021         return oldValue;
1022     }
1023 
1024     /**
1025      * Removes the specified node from the list.
1026      *
1027      * @param node  The node to remove
1028      * @throws NullPointerException if {@code node} is null
1029      */
1030     protected void removeNode(final Node<E> node) {
1031         Objects.requireNonNull(node, "node");
1032         node.previous.next = node.next;
1033         node.next.previous = node.previous;
1034         size--;
1035         modCount++;
1036     }
1037 
1038     /**
1039      * {@inheritDoc}
1040      * <p>
1041      * This implementation iterates over the elements of this list, checking each element in
1042      * turn to see if it's contained in {@code coll}. If it's not contained, it's removed
1043      * from this list. As a consequence, it is advised to use a collection type for
1044      * {@code coll} that provides a fast (for example O(1)) implementation of
1045      * {@link Collection#contains(Object)}.
1046      */
1047     @Override
1048     public boolean retainAll(final Collection<?> coll) {
1049         boolean modified = false;
1050         final Iterator<E> it = iterator();
1051         while (it.hasNext()) {
1052             if (!coll.contains(it.next())) {
1053                 it.remove();
1054                 modified = true;
1055             }
1056         }
1057         return modified;
1058     }
1059 
1060     @Override
1061     public E set(final int index, final E value) {
1062         final Node<E> node = getNode(index, false);
1063         final E oldValue = node.getValue();
1064         updateNode(node, value);
1065         return oldValue;
1066     }
1067 
1068     @Override
1069     public int size() {
1070         return size;
1071     }
1072 
1073     /**
1074      * Gets a sublist of the main list.
1075      *
1076      * @param fromIndexInclusive  The index to start from
1077      * @param toIndexExclusive  The index to end at
1078      * @return The new sublist
1079      */
1080     @Override
1081     public List<E> subList(final int fromIndexInclusive, final int toIndexExclusive) {
1082         return new LinkedSubList<>(this, fromIndexInclusive, toIndexExclusive);
1083     }
1084 
1085     @Override
1086     public Object[] toArray() {
1087         return toArray(new Object[size]);
1088     }
1089 
1090     @Override
1091     @SuppressWarnings("unchecked")
1092     public <T> T[] toArray(T[] array) {
1093         // Extend the array if needed
1094         if (array.length < size) {
1095             final Class<?> componentType = array.getClass().getComponentType();
1096             array = (T[]) Array.newInstance(componentType, size);
1097         }
1098         // Copy the values into the array
1099         int i = 0;
1100         for (Node<E> node = header.next; node != header; node = node.next, i++) {
1101             array[i] = (T) node.getValue();
1102         }
1103         // Set the value after the last value to null
1104         if (array.length > size) {
1105             array[size] = null;
1106         }
1107         return array;
1108     }
1109 
1110     @Override
1111     public String toString() {
1112         if (isEmpty()) {
1113             return "[]";
1114         }
1115         final StringBuilder buf = new StringBuilder(16 * size());
1116         buf.append(CollectionUtils.DEFAULT_TOSTRING_PREFIX);
1117 
1118         final Iterator<E> it = iterator();
1119         boolean hasNext = it.hasNext();
1120         while (hasNext) {
1121             final Object value = it.next();
1122             buf.append(value == this ? "(this Collection)" : value);
1123             hasNext = it.hasNext();
1124             if (hasNext) {
1125                 buf.append(", ");
1126             }
1127         }
1128         buf.append(CollectionUtils.DEFAULT_TOSTRING_SUFFIX);
1129         return buf.toString();
1130     }
1131 
1132     /**
1133      * Updates the node with a new value.
1134      * This implementation sets the value on the node.
1135      * Subclasses can override this to record the change.
1136      *
1137      * @param node  node to update
1138      * @param value  new value of the node
1139      */
1140     protected void updateNode(final Node<E> node, final E value) {
1141         node.setValue(value);
1142     }
1143 
1144 }