001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      https://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.collections4.list;
018
019import java.io.IOException;
020import java.io.ObjectInputStream;
021import java.io.ObjectOutputStream;
022import java.lang.reflect.Array;
023import java.util.AbstractList;
024import java.util.Collection;
025import java.util.ConcurrentModificationException;
026import java.util.Iterator;
027import java.util.List;
028import java.util.ListIterator;
029import java.util.NoSuchElementException;
030import java.util.Objects;
031
032import org.apache.commons.collections4.CollectionUtils;
033import org.apache.commons.collections4.OrderedIterator;
034
035/**
036 * An abstract implementation of a linked list which provides numerous points for
037 * subclasses to override.
038 * <p>
039 * Overridable methods are provided to change the storage node and to change how
040 * nodes are added to and removed. Hopefully, all you need for unusual subclasses
041 * is here.
042 * </p>
043 *
044 * @param <E> The type of elements in this list
045 * @since 3.0
046 * @deprecated Use {@link AbstractLinkedListJava21} instead
047 */
048@Deprecated
049public abstract class AbstractLinkedList<E> implements List<E> {
050
051    /*
052     * Implementation notes:
053     * - a standard circular doubly-linked list
054     * - a marker node is stored to mark the start and the end of the list
055     * - node creation and removal always occurs through createNode() and
056     *   removeNode().
057     * - a modification count is kept, with the same semantics as
058     * {@link java.util.LinkedList}.
059     * - respects {@link AbstractList#modCount}
060     */
061
062    /**
063     * A list iterator over the linked list.
064     *
065     * @param <E> The type of elements in this iterator.
066     */
067    protected static class LinkedListIterator<E> implements ListIterator<E>, OrderedIterator<E> {
068
069        /** The parent list */
070        protected final AbstractLinkedList<E> parent;
071
072        /**
073         * The node that will be returned by {@link #next()}. If this is equal
074         * to {@link AbstractLinkedList#header} then there are no more values to return.
075         */
076        protected Node<E> next;
077
078        /**
079         * The index of {@link #next}.
080         */
081        protected int nextIndex;
082
083        /**
084         * The last node that was returned by {@link #next()} or {@link
085         * #previous()}. Set to {@code null} if {@link #next()} or {@link
086         * #previous()} haven't been called, or if the node has been removed
087         * with {@link #remove()} or a new node added with {@link #add(Object)}.
088         * Should be accessed through {@link #getLastNodeReturned()} to enforce
089         * this behavior.
090         */
091        protected Node<E> current;
092
093        /**
094         * The modification count that the list is expected to have. If the list
095         * doesn't have this count, then a
096         * {@link ConcurrentModificationException} may be thrown by
097         * the operations.
098         */
099        protected int expectedModCount;
100
101        /**
102         * Create a ListIterator for a list.
103         *
104         * @param parent  The parent list.
105         * @param fromIndex  The starting index.
106         * @throws IndexOutOfBoundsException if fromIndex is less than 0 or greater than the size of the list.
107         */
108        protected LinkedListIterator(final AbstractLinkedList<E> parent, final int fromIndex)
109                throws IndexOutOfBoundsException {
110            this.parent = parent;
111            this.expectedModCount = parent.modCount;
112            this.next = parent.getNode(fromIndex, true);
113            this.nextIndex = fromIndex;
114        }
115
116        @Override
117        public void add(final E obj) {
118            checkModCount();
119            parent.addNodeBefore(next, obj);
120            current = null;
121            nextIndex++;
122            expectedModCount++;
123        }
124
125        /**
126         * Checks the modification count of the list is the value that this
127         * object expects.
128         *
129         * @throws ConcurrentModificationException If the list's modification
130         * count isn't the value that was expected.
131         */
132        protected void checkModCount() {
133            if (parent.modCount != expectedModCount) {
134                throw new ConcurrentModificationException();
135            }
136        }
137
138        /**
139         * Gets the last node returned.
140         *
141         * @return The last node returned
142         * @throws IllegalStateException If {@link #next()} or {@link #previous()} haven't been called,
143         * or if the node has been removed with {@link #remove()} or a new node added with {@link #add(Object)}.
144         */
145        protected Node<E> getLastNodeReturned() throws IllegalStateException {
146            if (current == null) {
147                throw new IllegalStateException();
148            }
149            return current;
150        }
151
152        @Override
153        public boolean hasNext() {
154            return next != parent.header;
155        }
156
157        @Override
158        public boolean hasPrevious() {
159            return next.previous != parent.header;
160        }
161
162        @Override
163        public E next() {
164            checkModCount();
165            if (!hasNext()) {
166                throw new NoSuchElementException("No element at index " + nextIndex + ".");
167            }
168            final E value = next.getValue();
169            current = next;
170            next = next.next;
171            nextIndex++;
172            return value;
173        }
174
175        @Override
176        public int nextIndex() {
177            return nextIndex;
178        }
179
180        @Override
181        public E previous() {
182            checkModCount();
183            if (!hasPrevious()) {
184                throw new NoSuchElementException("Already at start of list.");
185            }
186            next = next.previous;
187            final E value = next.getValue();
188            current = next;
189            nextIndex--;
190            return value;
191        }
192
193        @Override
194        public int previousIndex() {
195            // not normally overridden, as relative to nextIndex()
196            return nextIndex() - 1;
197        }
198
199        @Override
200        public void remove() {
201            checkModCount();
202            if (current == next) {
203                // remove() following previous()
204                next = next.next;
205                parent.removeNode(getLastNodeReturned());
206            } else {
207                // remove() following next()
208                parent.removeNode(getLastNodeReturned());
209                nextIndex--;
210            }
211            current = null;
212            expectedModCount++;
213        }
214
215        @Override
216        public void set(final E value) {
217            checkModCount();
218            getLastNodeReturned().setValue(value);
219        }
220
221    }
222
223    /**
224     * The sublist implementation for AbstractLinkedList.
225     *
226     * @param <E> The type of elements in this list.
227     */
228    protected static class LinkedSubList<E> extends AbstractList<E> {
229
230        /** The main list */
231        AbstractLinkedList<E> parent;
232
233        /** Offset from the main list */
234        int offset;
235
236        /** Sublist size */
237        int size;
238
239        /** Sublist modCount */
240        int expectedModCount;
241
242        /**
243         * Constructs a new instance.
244         *
245         * @param parent The parent AbstractLinkedList.
246         * @param fromIndex An index greater or equal to 0 and less than {@code toIndex}.
247         * @param toIndex An index greater than {@code fromIndex}.
248         */
249        protected LinkedSubList(final AbstractLinkedList<E> parent, final int fromIndex, final int toIndex) {
250            if (fromIndex < 0) {
251                throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
252            }
253            if (toIndex > parent.size()) {
254                throw new IndexOutOfBoundsException("toIndex = " + toIndex);
255            }
256            if (fromIndex > toIndex) {
257                throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
258            }
259            this.parent = parent;
260            this.offset = fromIndex;
261            this.size = toIndex - fromIndex;
262            this.expectedModCount = parent.modCount;
263        }
264
265        @Override
266        public void add(final int index, final E obj) {
267            rangeCheck(index, size + 1);
268            checkModCount();
269            parent.add(index + offset, obj);
270            expectedModCount = parent.modCount;
271            size++;
272            modCount++;
273        }
274
275        @Override
276        public boolean addAll(final Collection<? extends E> coll) {
277            return addAll(size, coll);
278        }
279
280        @Override
281        public boolean addAll(final int index, final Collection<? extends E> coll) {
282            rangeCheck(index, size + 1);
283            final int cSize = coll.size();
284            if (cSize == 0) {
285                return false;
286            }
287
288            checkModCount();
289            parent.addAll(offset + index, coll);
290            expectedModCount = parent.modCount;
291            size += cSize;
292            modCount++;
293            return true;
294        }
295
296        /**
297         * Throws a {@link ConcurrentModificationException} if this instance fails its concurrency check.
298         */
299        protected void checkModCount() {
300            if (parent.modCount != expectedModCount) {
301                throw new ConcurrentModificationException();
302            }
303        }
304
305        @Override
306        public void clear() {
307            checkModCount();
308            final Iterator<E> it = iterator();
309            while (it.hasNext()) {
310                it.next();
311                it.remove();
312            }
313        }
314
315        @Override
316        public E get(final int index) {
317            rangeCheck(index, size);
318            checkModCount();
319            return parent.get(index + offset);
320        }
321
322        @Override
323        public Iterator<E> iterator() {
324            checkModCount();
325            return parent.createSubListIterator(this);
326        }
327
328        @Override
329        public ListIterator<E> listIterator(final int index) {
330            rangeCheck(index, size + 1);
331            checkModCount();
332            return parent.createSubListListIterator(this, index);
333        }
334
335        /**
336         * Throws an {@link IndexOutOfBoundsException} if the given indices are out of bounds.
337         *
338         * @param index lower index.
339         * @param beyond upper index.
340         */
341        protected void rangeCheck(final int index, final int beyond) {
342            if (index < 0 || index >= beyond) {
343                throw new IndexOutOfBoundsException("Index '" + index + "' out of bounds for size '" + size + "'");
344            }
345        }
346
347        @Override
348        public E remove(final int index) {
349            rangeCheck(index, size);
350            checkModCount();
351            final E result = parent.remove(index + offset);
352            expectedModCount = parent.modCount;
353            size--;
354            modCount++;
355            return result;
356        }
357
358        @Override
359        public E set(final int index, final E obj) {
360            rangeCheck(index, size);
361            checkModCount();
362            return parent.set(index + offset, obj);
363        }
364
365        @Override
366        public int size() {
367            checkModCount();
368            return size;
369        }
370
371        @Override
372        public List<E> subList(final int fromIndexInclusive, final int toIndexExclusive) {
373            return new LinkedSubList<>(parent, fromIndexInclusive + offset, toIndexExclusive + offset);
374        }
375    }
376
377    /**
378     * A list iterator over the linked sub list.
379     *
380     * @param <E> The type of elements in this iterator.
381     */
382    protected static class LinkedSubListIterator<E> extends LinkedListIterator<E> {
383
384        /** The sub list. */
385        protected final LinkedSubList<E> sub;
386
387        /**
388         * Constructs a new instance.
389         *
390         * @param sub The sub-list.
391         * @param startIndex The starting index.
392         */
393        protected LinkedSubListIterator(final LinkedSubList<E> sub, final int startIndex) {
394            super(sub.parent, startIndex + sub.offset);
395            this.sub = sub;
396        }
397
398        @Override
399        public void add(final E obj) {
400            super.add(obj);
401            sub.expectedModCount = parent.modCount;
402            sub.size++;
403        }
404
405        @Override
406        public boolean hasNext() {
407            return nextIndex() < sub.size;
408        }
409
410        @Override
411        public boolean hasPrevious() {
412            return previousIndex() >= 0;
413        }
414
415        @Override
416        public int nextIndex() {
417            return super.nextIndex() - sub.offset;
418        }
419
420        @Override
421        public void remove() {
422            super.remove();
423            sub.expectedModCount = parent.modCount;
424            sub.size--;
425        }
426    }
427
428    /**
429     * A node within the linked list.
430     * <p>
431     * From Commons Collections 3.1, all access to the {@code value} property
432     * is via the methods on this class.
433     * </p>
434     *
435     * @param <E> The node value type.
436     */
437    protected static class Node<E> {
438
439        /** A pointer to the node before this node */
440        protected Node<E> previous;
441
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}