001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.collections4.list;
018
019import java.io.IOException;
020import java.io.ObjectInputStream;
021import java.io.ObjectOutputStream;
022import java.lang.reflect.Array;
023import java.util.AbstractList;
024import java.util.Collection;
025import java.util.ConcurrentModificationException;
026import java.util.Iterator;
027import java.util.List;
028import java.util.ListIterator;
029import java.util.NoSuchElementException;
030import java.util.Objects;
031
032import org.apache.commons.collections4.CollectionUtils;
033import org.apache.commons.collections4.OrderedIterator;
034
035/**
036 * An abstract implementation of a linked list which provides numerous points for
037 * subclasses to override.
038 * <p>
039 * Overridable methods are provided to change the storage node and to change how
040 * nodes are added to and removed. Hopefully, all you need for unusual subclasses
041 * is here.
042 * </p>
043 *
044 * @param <E> the type of elements in this list
045 * @since 3.0
046 * @deprecated use {@link AbstractLinkedListForJava21} instead
047 */
048@Deprecated
049public abstract class AbstractLinkedList<E> implements List<E> {
050
051    /*
052     * Implementation notes:
053     * - a standard circular doubly-linked list
054     * - a marker node is stored to mark the start and the end of the list
055     * - node creation and removal always occurs through createNode() and
056     *   removeNode().
057     * - a modification count is kept, with the same semantics as
058     * {@link java.util.LinkedList}.
059     * - respects {@link AbstractList#modCount}
060     */
061
062    /**
063     * A list iterator over the linked list.
064     *
065     * @param <E> the type of elements in this iterator.
066     */
067    protected static class LinkedListIterator<E> implements ListIterator<E>, OrderedIterator<E> {
068
069        /** The parent list */
070        protected final AbstractLinkedList<E> parent;
071
072        /**
073         * The node that will be returned by {@link #next()}. If this is equal
074         * to {@link AbstractLinkedList#header} then there are no more values to return.
075         */
076        protected Node<E> next;
077
078        /**
079         * The index of {@link #next}.
080         */
081        protected int nextIndex;
082
083        /**
084         * The last node that was returned by {@link #next()} or {@link
085         * #previous()}. Set to {@code null} if {@link #next()} or {@link
086         * #previous()} haven't been called, or if the node has been removed
087         * with {@link #remove()} or a new node added with {@link #add(Object)}.
088         * Should be accessed through {@link #getLastNodeReturned()} to enforce
089         * this behavior.
090         */
091        protected Node<E> current;
092
093        /**
094         * The modification count that the list is expected to have. If the list
095         * doesn't have this count, then a
096         * {@link java.util.ConcurrentModificationException} may be thrown by
097         * the operations.
098         */
099        protected int expectedModCount;
100
101        /**
102         * Create a ListIterator for a list.
103         *
104         * @param parent  the parent list
105         * @param fromIndex  the 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}