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    *      http://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 AbstractLinkedListForJava21} 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 java.util.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 index to start at
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 obj) {
217             checkModCount();
218             getLastNodeReturned().setValue(obj);
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         /** The main list */
230         AbstractLinkedList<E> parent;
231         /** Offset from the main list */
232         int offset;
233         /** Sublist size */
234         int size;
235         /** Sublist modCount */
236         int expectedModCount;
237 
238         protected LinkedSubList(final AbstractLinkedList<E> parent, final int fromIndex, final int toIndex) {
239             if (fromIndex < 0) {
240                 throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
241             }
242             if (toIndex > parent.size()) {
243                 throw new IndexOutOfBoundsException("toIndex = " + toIndex);
244             }
245             if (fromIndex > toIndex) {
246                 throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
247             }
248             this.parent = parent;
249             this.offset = fromIndex;
250             this.size = toIndex - fromIndex;
251             this.expectedModCount = parent.modCount;
252         }
253 
254         @Override
255         public void add(final int index, final E obj) {
256             rangeCheck(index, size + 1);
257             checkModCount();
258             parent.add(index + offset, obj);
259             expectedModCount = parent.modCount;
260             size++;
261             modCount++;
262         }
263 
264         @Override
265         public boolean addAll(final Collection<? extends E> coll) {
266             return addAll(size, coll);
267         }
268 
269         @Override
270         public boolean addAll(final int index, final Collection<? extends E> coll) {
271             rangeCheck(index, size + 1);
272             final int cSize = coll.size();
273             if (cSize == 0) {
274                 return false;
275             }
276 
277             checkModCount();
278             parent.addAll(offset + index, coll);
279             expectedModCount = parent.modCount;
280             size += cSize;
281             modCount++;
282             return true;
283         }
284 
285         protected void checkModCount() {
286             if (parent.modCount != expectedModCount) {
287                 throw new ConcurrentModificationException();
288             }
289         }
290 
291         @Override
292         public void clear() {
293             checkModCount();
294             final Iterator<E> it = iterator();
295             while (it.hasNext()) {
296                 it.next();
297                 it.remove();
298             }
299         }
300 
301         @Override
302         public E get(final int index) {
303             rangeCheck(index, size);
304             checkModCount();
305             return parent.get(index + offset);
306         }
307 
308         @Override
309         public Iterator<E> iterator() {
310             checkModCount();
311             return parent.createSubListIterator(this);
312         }
313 
314         @Override
315         public ListIterator<E> listIterator(final int index) {
316             rangeCheck(index, size + 1);
317             checkModCount();
318             return parent.createSubListListIterator(this, index);
319         }
320 
321         protected void rangeCheck(final int index, final int beyond) {
322             if (index < 0 || index >= beyond) {
323                 throw new IndexOutOfBoundsException("Index '" + index + "' out of bounds for size '" + size + "'");
324             }
325         }
326 
327         @Override
328         public E remove(final int index) {
329             rangeCheck(index, size);
330             checkModCount();
331             final E result = parent.remove(index + offset);
332             expectedModCount = parent.modCount;
333             size--;
334             modCount++;
335             return result;
336         }
337 
338         @Override
339         public E set(final int index, final E obj) {
340             rangeCheck(index, size);
341             checkModCount();
342             return parent.set(index + offset, obj);
343         }
344 
345         @Override
346         public int size() {
347             checkModCount();
348             return size;
349         }
350 
351         @Override
352         public List<E> subList(final int fromIndexInclusive, final int toIndexExclusive) {
353             return new LinkedSubList<>(parent, fromIndexInclusive + offset, toIndexExclusive + offset);
354         }
355     }
356 
357     /**
358      * A list iterator over the linked sub list.
359      *
360      * @param <E> the type of elements in this iterator.
361      */
362     protected static class LinkedSubListIterator<E> extends LinkedListIterator<E> {
363 
364         /** The sub list */
365         protected final LinkedSubList<E> sub;
366 
367         protected LinkedSubListIterator(final LinkedSubList<E> sub, final int startIndex) {
368             super(sub.parent, startIndex + sub.offset);
369             this.sub = sub;
370         }
371 
372         @Override
373         public void add(final E obj) {
374             super.add(obj);
375             sub.expectedModCount = parent.modCount;
376             sub.size++;
377         }
378 
379         @Override
380         public boolean hasNext() {
381             return nextIndex() < sub.size;
382         }
383 
384         @Override
385         public boolean hasPrevious() {
386             return previousIndex() >= 0;
387         }
388 
389         @Override
390         public int nextIndex() {
391             return super.nextIndex() - sub.offset;
392         }
393 
394         @Override
395         public void remove() {
396             super.remove();
397             sub.expectedModCount = parent.modCount;
398             sub.size--;
399         }
400     }
401 
402     /**
403      * A node within the linked list.
404      * <p>
405      * From Commons Collections 3.1, all access to the {@code value} property
406      * is via the methods on this class.
407      */
408     protected static class Node<E> {
409 
410         /** A pointer to the node before this node */
411         protected Node<E> previous;
412         /** A pointer to the node after this node */
413         protected Node<E> next;
414         /** The object contained within this node */
415         protected E value;
416 
417         /**
418          * Constructs a new header node.
419          */
420         protected Node() {
421             previous = this;
422             next = this;
423         }
424 
425         /**
426          * Constructs a new node.
427          *
428          * @param value  the value to store
429          */
430         protected Node(final E value) {
431             this.value = value;
432         }
433 
434         /**
435          * Constructs a new node.
436          *
437          * @param previous  the previous node in the list
438          * @param next  the next node in the list
439          * @param value  the value to store
440          */
441         protected Node(final Node<E> previous, final Node<E> next, final E value) {
442             this.previous = previous;
443             this.next = next;
444             this.value = value;
445         }
446 
447         /**
448          * Gets the next node.
449          *
450          * @return the next node
451          * @since 3.1
452          */
453         protected Node<E> getNextNode() {
454             return next;
455         }
456 
457         /**
458          * Gets the previous node.
459          *
460          * @return the previous node
461          * @since 3.1
462          */
463         protected Node<E> getPreviousNode() {
464             return previous;
465         }
466 
467         /**
468          * Gets the value of the node.
469          *
470          * @return the value
471          * @since 3.1
472          */
473         protected E getValue() {
474             return value;
475         }
476 
477         /**
478          * Sets the next node.
479          *
480          * @param next  the next node
481          * @since 3.1
482          */
483         protected void setNextNode(final Node<E> next) {
484             this.next = next;
485         }
486 
487         /**
488          * Sets the previous node.
489          *
490          * @param previous  the previous node
491          * @since 3.1
492          */
493         protected void setPreviousNode(final Node<E> previous) {
494             this.previous = previous;
495         }
496 
497         /**
498          * Sets the value of the node.
499          *
500          * @param value  the value
501          * @since 3.1
502          */
503         protected void setValue(final E value) {
504             this.value = value;
505         }
506     }
507 
508     /**
509      * A {@link Node} which indicates the start and end of the list and does not
510      * hold a value. The value of {@code next} is the first item in the
511      * list. The value of {@code previous} is the last item in the list.
512      */
513     transient Node<E> header;
514 
515     /** The size of the list */
516     transient int size;
517 
518     /** Modification count for iterators */
519     transient int modCount;
520 
521     /**
522      * Constructor that does nothing (intended for deserialization).
523      * <p>
524      * If this constructor is used by a serializable subclass then the init()
525      * method must be called.
526      */
527     protected AbstractLinkedList() {
528     }
529 
530     /**
531      * Constructs a list copying data from the specified collection.
532      *
533      * @param coll  the collection to copy
534      */
535     protected AbstractLinkedList(final Collection<? extends E> coll) {
536         init();
537         addAll(coll);
538     }
539 
540     @Override
541     public boolean add(final E value) {
542         addLast(value);
543         return true;
544     }
545 
546     @Override
547     public void add(final int index, final E value) {
548         final Node<E> node = getNode(index, true);
549         addNodeBefore(node, value);
550     }
551 
552     @Override
553     public boolean addAll(final Collection<? extends E> coll) {
554         return addAll(size, coll);
555     }
556 
557     @Override
558     public boolean addAll(final int index, final Collection<? extends E> coll) {
559         final Node<E> node = getNode(index, true);
560         for (final E e : coll) {
561             addNodeBefore(node, e);
562         }
563         return true;
564     }
565 
566     public boolean addFirst(final E o) {
567         addNodeAfter(header, o);
568         return true;
569     }
570 
571     public boolean addLast(final E o) {
572         addNodeBefore(header, o);
573         return true;
574     }
575 
576     /**
577      * Inserts a new node into the list.
578      *
579      * @param nodeToInsert  new node to insert
580      * @param insertBeforeNode  node to insert before
581      * @throws NullPointerException if either node is null
582      */
583     protected void addNode(final Node<E> nodeToInsert, final Node<E> insertBeforeNode) {
584         Objects.requireNonNull(nodeToInsert, "nodeToInsert");
585         Objects.requireNonNull(insertBeforeNode, "insertBeforeNode");
586         nodeToInsert.next = insertBeforeNode;
587         nodeToInsert.previous = insertBeforeNode.previous;
588         insertBeforeNode.previous.next = nodeToInsert;
589         insertBeforeNode.previous = nodeToInsert;
590         size++;
591         modCount++;
592     }
593 
594     /**
595      * Creates a new node with the specified object as its
596      * {@code value} and inserts it after {@code node}.
597      * <p>
598      * This implementation uses {@link #createNode(Object)} and
599      * {@link #addNode(AbstractLinkedList.Node,AbstractLinkedList.Node)}.
600      *
601      * @param node  node to insert after
602      * @param value  value of the newly added node
603      * @throws NullPointerException if {@code node} is null
604      */
605     protected void addNodeAfter(final Node<E> node, final E value) {
606         final Node<E> newNode = createNode(value);
607         addNode(newNode, node.next);
608     }
609 
610     /**
611      * Creates a new node with the specified object as its
612      * {@code value} and inserts it before {@code node}.
613      * <p>
614      * This implementation uses {@link #createNode(Object)} and
615      * {@link #addNode(AbstractLinkedList.Node,AbstractLinkedList.Node)}.
616      *
617      * @param node  node to insert before
618      * @param value  value of the newly added node
619      * @throws NullPointerException if {@code node} is null
620      */
621     protected void addNodeBefore(final Node<E> node, final E value) {
622         final Node<E> newNode = createNode(value);
623         addNode(newNode, node);
624     }
625 
626     @Override
627     public void clear() {
628         removeAllNodes();
629     }
630 
631     @Override
632     public boolean contains(final Object value) {
633         return indexOf(value) != -1;
634     }
635 
636     @Override
637     public boolean containsAll(final Collection<?> coll) {
638         for (final Object o : coll) {
639             if (!contains(o)) {
640                 return false;
641             }
642         }
643         return true;
644     }
645 
646     /**
647      * Creates a new node with previous, next and element all set to null.
648      * This implementation creates a new empty Node.
649      * Subclasses can override this to create a different class.
650      *
651      * @return  newly created node
652      */
653     protected Node<E> createHeaderNode() {
654         return new Node<>();
655     }
656 
657     /**
658      * Creates a new node with the specified properties.
659      * This implementation creates a new Node with data.
660      * Subclasses can override this to create a different class.
661      *
662      * @param value  value of the new node
663      * @return a new node containing the value
664      */
665     protected Node<E> createNode(final E value) {
666         return new Node<>(value);
667     }
668 
669     /**
670      * Creates an iterator for the sublist.
671      *
672      * @param subList  the sublist to get an iterator for
673      * @return a new iterator on the given sublist
674      */
675     protected Iterator<E> createSubListIterator(final LinkedSubList<E> subList) {
676         return createSubListListIterator(subList, 0);
677     }
678 
679     /**
680      * Creates a list iterator for the sublist.
681      *
682      * @param subList  the sublist to get an iterator for
683      * @param fromIndex  the index to start from, relative to the sublist
684      * @return a new list iterator on the given sublist
685      */
686     protected ListIterator<E> createSubListListIterator(final LinkedSubList<E> subList, final int fromIndex) {
687         return new LinkedSubListIterator<>(subList, fromIndex);
688     }
689 
690     /**
691      * Deserializes the data held in this object to the stream specified.
692      * <p>
693      * The first serializable subclass must call this method from
694      * {@code readObject}.
695      *
696      * @param inputStream  the stream to read the object from
697      * @throws IOException  if any error occurs while reading from the stream
698      * @throws ClassNotFoundException  if a class read from the stream can not be loaded
699      */
700     @SuppressWarnings("unchecked")
701     protected void doReadObject(final ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
702         init();
703         final int size = inputStream.readInt();
704         for (int i = 0; i < size; i++) {
705             add((E) inputStream.readObject());
706         }
707     }
708 
709     /**
710      * Serializes the data held in this object to the stream specified.
711      * <p>
712      * The first serializable subclass must call this method from
713      * {@code writeObject}.
714      *
715      * @param outputStream  the stream to write the object to
716      * @throws IOException  if anything goes wrong
717      */
718     protected void doWriteObject(final ObjectOutputStream outputStream) throws IOException {
719         // Write the size so we know how many nodes to read back
720         outputStream.writeInt(size());
721         for (final E e : this) {
722             outputStream.writeObject(e);
723         }
724     }
725 
726     @Override
727     public boolean equals(final Object obj) {
728         if (obj == this) {
729             return true;
730         }
731         if (!(obj instanceof List)) {
732             return false;
733         }
734         final List<?> other = (List<?>) obj;
735         if (other.size() != size()) {
736             return false;
737         }
738         final ListIterator<?> it1 = listIterator();
739         final ListIterator<?> it2 = other.listIterator();
740         while (it1.hasNext() && it2.hasNext()) {
741             if (!Objects.equals(it1.next(), it2.next())) {
742                 return false;
743             }
744         }
745         return !(it1.hasNext() || it2.hasNext());
746     }
747 
748     @Override
749     public E get(final int index) {
750         final Node<E> node = getNode(index, false);
751         return node.getValue();
752     }
753 
754     public E getFirst() {
755         final Node<E> node = header.next;
756         if (node == header) {
757             throw new NoSuchElementException();
758         }
759         return node.getValue();
760     }
761 
762     public E getLast() {
763         final Node<E> node = header.previous;
764         if (node == header) {
765             throw new NoSuchElementException();
766         }
767         return node.getValue();
768     }
769 
770     /**
771      * Gets the node at a particular index.
772      *
773      * @param index  the index, starting from 0
774      * @param endMarkerAllowed  whether or not the end marker can be returned if
775      * startIndex is set to the list's size
776      * @return the node at the given index
777      * @throws IndexOutOfBoundsException if the index is less than 0; equal to
778      * the size of the list and endMakerAllowed is false; or greater than the
779      * size of the list
780      */
781     protected Node<E> getNode(final int index, final boolean endMarkerAllowed) throws IndexOutOfBoundsException {
782         // Check the index is within the bounds
783         if (index < 0) {
784             throw new IndexOutOfBoundsException("Couldn't get the node: " +
785                     "index (" + index + ") less than zero.");
786         }
787         if (!endMarkerAllowed && index == size) {
788             throw new IndexOutOfBoundsException("Couldn't get the node: " +
789                     "index (" + index + ") is the size of the list.");
790         }
791         if (index > size) {
792             throw new IndexOutOfBoundsException("Couldn't get the node: " +
793                     "index (" + index + ") greater than the size of the " +
794                     "list (" + size + ").");
795         }
796         // Search the list and get the node
797         Node<E> node;
798         if (index < size / 2) {
799             // Search forwards
800             node = header.next;
801             for (int currentIndex = 0; currentIndex < index; currentIndex++) {
802                 node = node.next;
803             }
804         } else {
805             // Search backwards
806             node = header;
807             for (int currentIndex = size; currentIndex > index; currentIndex--) {
808                 node = node.previous;
809             }
810         }
811         return node;
812     }
813 
814     @Override
815     public int hashCode() {
816         int hashCode = 1;
817         for (final E e : this) {
818             hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
819         }
820         return hashCode;
821     }
822 
823     @Override
824     public int indexOf(final Object value) {
825         int i = 0;
826         for (Node<E> node = header.next; node != header; node = node.next) {
827             if (isEqualValue(node.getValue(), value)) {
828                 return i;
829             }
830             i++;
831         }
832         return CollectionUtils.INDEX_NOT_FOUND;
833     }
834 
835     /**
836      * The equivalent of a default constructor, broken out so it can be called
837      * by any constructor and by {@code readObject}.
838      * Subclasses which override this method should make sure they call super,
839      * so the list is initialized properly.
840      */
841     protected void init() {
842         header = createHeaderNode();
843     }
844 
845     @Override
846     public boolean isEmpty() {
847         return size() == 0;
848     }
849 
850     /**
851      * Compares two values for equals.
852      * This implementation uses the equals method.
853      * Subclasses can override this to match differently.
854      *
855      * @param value1  the first value to compare, may be null
856      * @param value2  the second value to compare, may be null
857      * @return true if equal
858      */
859     protected boolean isEqualValue(final Object value1, final Object value2) {
860         return Objects.equals(value1, value2);
861     }
862 
863     @Override
864     public Iterator<E> iterator() {
865         return listIterator();
866     }
867 
868     @Override
869     public int lastIndexOf(final Object value) {
870         int i = size - 1;
871         for (Node<E> node = header.previous; node != header; node = node.previous) {
872             if (isEqualValue(node.getValue(), value)) {
873                 return i;
874             }
875             i--;
876         }
877         return CollectionUtils.INDEX_NOT_FOUND;
878     }
879 
880     @Override
881     public ListIterator<E> listIterator() {
882         return new LinkedListIterator<>(this, 0);
883     }
884 
885     @Override
886     public ListIterator<E> listIterator(final int fromIndex) {
887         return new LinkedListIterator<>(this, fromIndex);
888     }
889 
890     @Override
891     public E remove(final int index) {
892         final Node<E> node = getNode(index, false);
893         final E oldValue = node.getValue();
894         removeNode(node);
895         return oldValue;
896     }
897 
898     @Override
899     public boolean remove(final Object value) {
900         for (Node<E> node = header.next; node != header; node = node.next) {
901             if (isEqualValue(node.getValue(), value)) {
902                 removeNode(node);
903                 return true;
904             }
905         }
906         return false;
907     }
908 
909     /**
910      * {@inheritDoc}
911      * <p>
912      * This implementation iterates over the elements of this list, checking each element in
913      * turn to see if it's contained in {@code coll}. If it's contained, it's removed
914      * from this list. As a consequence, it is advised to use a collection type for
915      * {@code coll} that provides a fast (e.g. O(1)) implementation of
916      * {@link Collection#contains(Object)}.
917      */
918     @Override
919     public boolean removeAll(final Collection<?> coll) {
920         boolean modified = false;
921         final Iterator<E> it = iterator();
922         while (it.hasNext()) {
923             if (coll.contains(it.next())) {
924                 it.remove();
925                 modified = true;
926             }
927         }
928         return modified;
929     }
930 
931     /**
932      * Removes all nodes by resetting the circular list marker.
933      */
934     protected void removeAllNodes() {
935         header.next = header;
936         header.previous = header;
937         size = 0;
938         modCount++;
939     }
940 
941     public E removeFirst() {
942         final Node<E> node = header.next;
943         if (node == header) {
944             throw new NoSuchElementException();
945         }
946         final E oldValue = node.getValue();
947         removeNode(node);
948         return oldValue;
949     }
950 
951     public E removeLast() {
952         final Node<E> node = header.previous;
953         if (node == header) {
954             throw new NoSuchElementException();
955         }
956         final E oldValue = node.getValue();
957         removeNode(node);
958         return oldValue;
959     }
960 
961     /**
962      * Removes the specified node from the list.
963      *
964      * @param node  the node to remove
965      * @throws NullPointerException if {@code node} is null
966      */
967     protected void removeNode(final Node<E> node) {
968         Objects.requireNonNull(node, "node");
969         node.previous.next = node.next;
970         node.next.previous = node.previous;
971         size--;
972         modCount++;
973     }
974 
975     /**
976      * {@inheritDoc}
977      * <p>
978      * This implementation iterates over the elements of this list, checking each element in
979      * turn to see if it's contained in {@code coll}. If it's not contained, it's removed
980      * from this list. As a consequence, it is advised to use a collection type for
981      * {@code coll} that provides a fast (e.g. O(1)) implementation of
982      * {@link Collection#contains(Object)}.
983      */
984     @Override
985     public boolean retainAll(final Collection<?> coll) {
986         boolean modified = false;
987         final Iterator<E> it = iterator();
988         while (it.hasNext()) {
989             if (!coll.contains(it.next())) {
990                 it.remove();
991                 modified = true;
992             }
993         }
994         return modified;
995     }
996 
997     @Override
998     public E set(final int index, final E value) {
999         final Node<E> node = getNode(index, false);
1000         final E oldValue = node.getValue();
1001         updateNode(node, value);
1002         return oldValue;
1003     }
1004 
1005     @Override
1006     public int size() {
1007         return size;
1008     }
1009 
1010     /**
1011      * Gets a sublist of the main list.
1012      *
1013      * @param fromIndexInclusive  the index to start from
1014      * @param toIndexExclusive  the index to end at
1015      * @return the new sublist
1016      */
1017     @Override
1018     public List<E> subList(final int fromIndexInclusive, final int toIndexExclusive) {
1019         return new LinkedSubList<>(this, fromIndexInclusive, toIndexExclusive);
1020     }
1021 
1022     @Override
1023     public Object[] toArray() {
1024         return toArray(new Object[size]);
1025     }
1026 
1027     @Override
1028     @SuppressWarnings("unchecked")
1029     public <T> T[] toArray(T[] array) {
1030         // Extend the array if needed
1031         if (array.length < size) {
1032             final Class<?> componentType = array.getClass().getComponentType();
1033             array = (T[]) Array.newInstance(componentType, size);
1034         }
1035         // Copy the values into the array
1036         int i = 0;
1037         for (Node<E> node = header.next; node != header; node = node.next, i++) {
1038             array[i] = (T) node.getValue();
1039         }
1040         // Set the value after the last value to null
1041         if (array.length > size) {
1042             array[size] = null;
1043         }
1044         return array;
1045     }
1046 
1047     @Override
1048     public String toString() {
1049         if (isEmpty()) {
1050             return "[]";
1051         }
1052         final StringBuilder buf = new StringBuilder(16 * size());
1053         buf.append(CollectionUtils.DEFAULT_TOSTRING_PREFIX);
1054 
1055         final Iterator<E> it = iterator();
1056         boolean hasNext = it.hasNext();
1057         while (hasNext) {
1058             final Object value = it.next();
1059             buf.append(value == this ? "(this Collection)" : value);
1060             hasNext = it.hasNext();
1061             if (hasNext) {
1062                 buf.append(", ");
1063             }
1064         }
1065         buf.append(CollectionUtils.DEFAULT_TOSTRING_SUFFIX);
1066         return buf.toString();
1067     }
1068 
1069     /**
1070      * Updates the node with a new value.
1071      * This implementation sets the value on the node.
1072      * Subclasses can override this to record the change.
1073      *
1074      * @param node  node to update
1075      * @param value  new value of the node
1076      */
1077     protected void updateNode(final Node<E> node, final E value) {
1078         node.setValue(value);
1079     }
1080 
1081 }