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 * This is a copy of AbstractLinkedList, modified to be compatible with Java 21
044 * (see COLLECTIONS-842 for details).
045 *
046 * @param <E> the type of elements in this list
047 * @since 3.0
048 */
049public abstract class AbstractLinkedListForJava21<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 AbstractLinkedListForJava21<E> parent;
071
072        /**
073         * The node that will be returned by {@link #next()}. If this is equal
074         * to {@link AbstractLinkedListForJava21#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 AbstractLinkedListForJava21<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 AbstractLinkedListForJava21.
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        AbstractLinkedListForJava21<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 AbstractLinkedListForJava21<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 AbstractLinkedListForJava21() {
528    }
529
530    /**
531     * Constructs a list copying data from the specified collection.
532     *
533     * @param coll  the collection to copy
534     */
535    protected AbstractLinkedListForJava21(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 void addFirst(final E o) {
567        addNodeAfter(header, o);
568    }
569
570    public void addLast(final E o) {
571        addNodeBefore(header, o);
572    }
573
574    /**
575     * Inserts a new node into the list.
576     *
577     * @param nodeToInsert  new node to insert
578     * @param insertBeforeNode  node to insert before
579     * @throws NullPointerException if either node is null
580     */
581    protected void addNode(final Node<E> nodeToInsert, final Node<E> insertBeforeNode) {
582        Objects.requireNonNull(nodeToInsert, "nodeToInsert");
583        Objects.requireNonNull(insertBeforeNode, "insertBeforeNode");
584        nodeToInsert.next = insertBeforeNode;
585        nodeToInsert.previous = insertBeforeNode.previous;
586        insertBeforeNode.previous.next = nodeToInsert;
587        insertBeforeNode.previous = nodeToInsert;
588        size++;
589        modCount++;
590    }
591
592    /**
593     * Creates a new node with the specified object as its
594     * {@code value} and inserts it after {@code node}.
595     * <p>
596     * This implementation uses {@link #createNode(Object)} and
597     * {@link #addNode(AbstractLinkedListForJava21.Node,AbstractLinkedListForJava21.Node)}.
598     *
599     * @param node  node to insert after
600     * @param value  value of the newly added node
601     * @throws NullPointerException if {@code node} is null
602     */
603    protected void addNodeAfter(final Node<E> node, final E value) {
604        final Node<E> newNode = createNode(value);
605        addNode(newNode, node.next);
606    }
607
608    /**
609     * Creates a new node with the specified object as its
610     * {@code value} and inserts it before {@code node}.
611     * <p>
612     * This implementation uses {@link #createNode(Object)} and
613     * {@link #addNode(AbstractLinkedListForJava21.Node,AbstractLinkedListForJava21.Node)}.
614     *
615     * @param node  node to insert before
616     * @param value  value of the newly added node
617     * @throws NullPointerException if {@code node} is null
618     */
619    protected void addNodeBefore(final Node<E> node, final E value) {
620        final Node<E> newNode = createNode(value);
621        addNode(newNode, node);
622    }
623
624    @Override
625    public void clear() {
626        removeAllNodes();
627    }
628
629    @Override
630    public boolean contains(final Object value) {
631        return indexOf(value) != -1;
632    }
633
634    @Override
635    public boolean containsAll(final Collection<?> coll) {
636        for (final Object o : coll) {
637            if (!contains(o)) {
638                return false;
639            }
640        }
641        return true;
642    }
643
644    /**
645     * Creates a new node with previous, next and element all set to null.
646     * This implementation creates a new empty Node.
647     * Subclasses can override this to create a different class.
648     *
649     * @return  newly created node
650     */
651    protected Node<E> createHeaderNode() {
652        return new Node<>();
653    }
654
655    /**
656     * Creates a new node with the specified properties.
657     * This implementation creates a new Node with data.
658     * Subclasses can override this to create a different class.
659     *
660     * @param value  value of the new node
661     * @return a new node containing the value
662     */
663    protected Node<E> createNode(final E value) {
664        return new Node<>(value);
665    }
666
667    /**
668     * Creates an iterator for the sublist.
669     *
670     * @param subList  the sublist to get an iterator for
671     * @return a new iterator on the given sublist
672     */
673    protected Iterator<E> createSubListIterator(final LinkedSubList<E> subList) {
674        return createSubListListIterator(subList, 0);
675    }
676
677    /**
678     * Creates a list iterator for the sublist.
679     *
680     * @param subList  the sublist to get an iterator for
681     * @param fromIndex  the index to start from, relative to the sublist
682     * @return a new list iterator on the given sublist
683     */
684    protected ListIterator<E> createSubListListIterator(final LinkedSubList<E> subList, final int fromIndex) {
685        return new LinkedSubListIterator<>(subList, fromIndex);
686    }
687
688    /**
689     * Deserializes the data held in this object to the stream specified.
690     * <p>
691     * The first serializable subclass must call this method from
692     * {@code readObject}.
693     *
694     * @param inputStream  the stream to read the object from
695     * @throws IOException  if any error occurs while reading from the stream
696     * @throws ClassNotFoundException  if a class read from the stream can not be loaded
697     */
698    @SuppressWarnings("unchecked")
699    protected void doReadObject(final ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
700        init();
701        final int size = inputStream.readInt();
702        for (int i = 0; i < size; i++) {
703            add((E) inputStream.readObject());
704        }
705    }
706
707    /**
708     * Serializes the data held in this object to the stream specified.
709     * <p>
710     * The first serializable subclass must call this method from
711     * {@code writeObject}.
712     *
713     * @param outputStream  the stream to write the object to
714     * @throws IOException  if anything goes wrong
715     */
716    protected void doWriteObject(final ObjectOutputStream outputStream) throws IOException {
717        // Write the size so we know how many nodes to read back
718        outputStream.writeInt(size());
719        for (final E e : this) {
720            outputStream.writeObject(e);
721        }
722    }
723
724    @Override
725    public boolean equals(final Object obj) {
726        if (obj == this) {
727            return true;
728        }
729        if (!(obj instanceof List)) {
730            return false;
731        }
732        final List<?> other = (List<?>) obj;
733        if (other.size() != size()) {
734            return false;
735        }
736        final ListIterator<?> it1 = listIterator();
737        final ListIterator<?> it2 = other.listIterator();
738        while (it1.hasNext() && it2.hasNext()) {
739            if (!Objects.equals(it1.next(), it2.next())) {
740                return false;
741            }
742        }
743        return !(it1.hasNext() || it2.hasNext());
744    }
745
746    @Override
747    public E get(final int index) {
748        final Node<E> node = getNode(index, false);
749        return node.getValue();
750    }
751
752    public E getFirst() {
753        final Node<E> node = header.next;
754        if (node == header) {
755            throw new NoSuchElementException();
756        }
757        return node.getValue();
758    }
759
760    public E getLast() {
761        final Node<E> node = header.previous;
762        if (node == header) {
763            throw new NoSuchElementException();
764        }
765        return node.getValue();
766    }
767
768    /**
769     * Gets the node at a particular index.
770     *
771     * @param index  the index, starting from 0
772     * @param endMarkerAllowed  whether or not the end marker can be returned if
773     * startIndex is set to the list's size
774     * @return the node at the given index
775     * @throws IndexOutOfBoundsException if the index is less than 0; equal to
776     * the size of the list and endMakerAllowed is false; or greater than the
777     * size of the list
778     */
779    protected Node<E> getNode(final int index, final boolean endMarkerAllowed) throws IndexOutOfBoundsException {
780        // Check the index is within the bounds
781        if (index < 0) {
782            throw new IndexOutOfBoundsException("Couldn't get the node: " +
783                    "index (" + index + ") less than zero.");
784        }
785        if (!endMarkerAllowed && index == size) {
786            throw new IndexOutOfBoundsException("Couldn't get the node: " +
787                    "index (" + index + ") is the size of the list.");
788        }
789        if (index > size) {
790            throw new IndexOutOfBoundsException("Couldn't get the node: " +
791                    "index (" + index + ") greater than the size of the " +
792                    "list (" + size + ").");
793        }
794        // Search the list and get the node
795        Node<E> node;
796        if (index < size / 2) {
797            // Search forwards
798            node = header.next;
799            for (int currentIndex = 0; currentIndex < index; currentIndex++) {
800                node = node.next;
801            }
802        } else {
803            // Search backwards
804            node = header;
805            for (int currentIndex = size; currentIndex > index; currentIndex--) {
806                node = node.previous;
807            }
808        }
809        return node;
810    }
811
812    @Override
813    public int hashCode() {
814        int hashCode = 1;
815        for (final E e : this) {
816            hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
817        }
818        return hashCode;
819    }
820
821    @Override
822    public int indexOf(final Object value) {
823        int i = 0;
824        for (Node<E> node = header.next; node != header; node = node.next) {
825            if (isEqualValue(node.getValue(), value)) {
826                return i;
827            }
828            i++;
829        }
830        return CollectionUtils.INDEX_NOT_FOUND;
831    }
832
833    /**
834     * The equivalent of a default constructor, broken out so it can be called
835     * by any constructor and by {@code readObject}.
836     * Subclasses which override this method should make sure they call super,
837     * so the list is initialized properly.
838     */
839    protected void init() {
840        header = createHeaderNode();
841    }
842
843    @Override
844    public boolean isEmpty() {
845        return size() == 0;
846    }
847
848    /**
849     * Compares two values for equals.
850     * This implementation uses the equals method.
851     * Subclasses can override this to match differently.
852     *
853     * @param value1  the first value to compare, may be null
854     * @param value2  the second value to compare, may be null
855     * @return true if equal
856     */
857    protected boolean isEqualValue(final Object value1, final Object value2) {
858        return Objects.equals(value1, value2);
859    }
860
861    @Override
862    public Iterator<E> iterator() {
863        return listIterator();
864    }
865
866    @Override
867    public int lastIndexOf(final Object value) {
868        int i = size - 1;
869        for (Node<E> node = header.previous; node != header; node = node.previous) {
870            if (isEqualValue(node.getValue(), value)) {
871                return i;
872            }
873            i--;
874        }
875        return CollectionUtils.INDEX_NOT_FOUND;
876    }
877
878    @Override
879    public ListIterator<E> listIterator() {
880        return new LinkedListIterator<>(this, 0);
881    }
882
883    @Override
884    public ListIterator<E> listIterator(final int fromIndex) {
885        return new LinkedListIterator<>(this, fromIndex);
886    }
887
888    @Override
889    public E remove(final int index) {
890        final Node<E> node = getNode(index, false);
891        final E oldValue = node.getValue();
892        removeNode(node);
893        return oldValue;
894    }
895
896    @Override
897    public boolean remove(final Object value) {
898        for (Node<E> node = header.next; node != header; node = node.next) {
899            if (isEqualValue(node.getValue(), value)) {
900                removeNode(node);
901                return true;
902            }
903        }
904        return false;
905    }
906
907    /**
908     * {@inheritDoc}
909     * <p>
910     * This implementation iterates over the elements of this list, checking each element in
911     * turn to see if it's contained in {@code coll}. If it's contained, it's removed
912     * from this list. As a consequence, it is advised to use a collection type for
913     * {@code coll} that provides a fast (e.g. O(1)) implementation of
914     * {@link Collection#contains(Object)}.
915     */
916    @Override
917    public boolean removeAll(final Collection<?> coll) {
918        boolean modified = false;
919        final Iterator<E> it = iterator();
920        while (it.hasNext()) {
921            if (coll.contains(it.next())) {
922                it.remove();
923                modified = true;
924            }
925        }
926        return modified;
927    }
928
929    /**
930     * Removes all nodes by resetting the circular list marker.
931     */
932    protected void removeAllNodes() {
933        header.next = header;
934        header.previous = header;
935        size = 0;
936        modCount++;
937    }
938
939    public E removeFirst() {
940        final Node<E> node = header.next;
941        if (node == header) {
942            throw new NoSuchElementException();
943        }
944        final E oldValue = node.getValue();
945        removeNode(node);
946        return oldValue;
947    }
948
949    public E removeLast() {
950        final Node<E> node = header.previous;
951        if (node == header) {
952            throw new NoSuchElementException();
953        }
954        final E oldValue = node.getValue();
955        removeNode(node);
956        return oldValue;
957    }
958
959    /**
960     * Removes the specified node from the list.
961     *
962     * @param node  the node to remove
963     * @throws NullPointerException if {@code node} is null
964     */
965    protected void removeNode(final Node<E> node) {
966        Objects.requireNonNull(node, "node");
967        node.previous.next = node.next;
968        node.next.previous = node.previous;
969        size--;
970        modCount++;
971    }
972
973    /**
974     * {@inheritDoc}
975     * <p>
976     * This implementation iterates over the elements of this list, checking each element in
977     * turn to see if it's contained in {@code coll}. If it's not contained, it's removed
978     * from this list. As a consequence, it is advised to use a collection type for
979     * {@code coll} that provides a fast (e.g. O(1)) implementation of
980     * {@link Collection#contains(Object)}.
981     */
982    @Override
983    public boolean retainAll(final Collection<?> coll) {
984        boolean modified = false;
985        final Iterator<E> it = iterator();
986        while (it.hasNext()) {
987            if (!coll.contains(it.next())) {
988                it.remove();
989                modified = true;
990            }
991        }
992        return modified;
993    }
994
995    @Override
996    public E set(final int index, final E value) {
997        final Node<E> node = getNode(index, false);
998        final E oldValue = node.getValue();
999        updateNode(node, value);
1000        return oldValue;
1001    }
1002
1003    @Override
1004    public int size() {
1005        return size;
1006    }
1007
1008    /**
1009     * Gets a sublist of the main list.
1010     *
1011     * @param fromIndexInclusive  the index to start from
1012     * @param toIndexExclusive  the index to end at
1013     * @return the new sublist
1014     */
1015    @Override
1016    public List<E> subList(final int fromIndexInclusive, final int toIndexExclusive) {
1017        return new LinkedSubList<>(this, fromIndexInclusive, toIndexExclusive);
1018    }
1019
1020    @Override
1021    public Object[] toArray() {
1022        return toArray(new Object[size]);
1023    }
1024
1025    @Override
1026    @SuppressWarnings("unchecked")
1027    public <T> T[] toArray(T[] array) {
1028        // Extend the array if needed
1029        if (array.length < size) {
1030            final Class<?> componentType = array.getClass().getComponentType();
1031            array = (T[]) Array.newInstance(componentType, size);
1032        }
1033        // Copy the values into the array
1034        int i = 0;
1035        for (Node<E> node = header.next; node != header; node = node.next, i++) {
1036            array[i] = (T) node.getValue();
1037        }
1038        // Set the value after the last value to null
1039        if (array.length > size) {
1040            array[size] = null;
1041        }
1042        return array;
1043    }
1044
1045    @Override
1046    public String toString() {
1047        if (isEmpty()) {
1048            return "[]";
1049        }
1050        final StringBuilder buf = new StringBuilder(16 * size());
1051        buf.append(CollectionUtils.DEFAULT_TOSTRING_PREFIX);
1052
1053        final Iterator<E> it = iterator();
1054        boolean hasNext = it.hasNext();
1055        while (hasNext) {
1056            final Object value = it.next();
1057            buf.append(value == this ? "(this Collection)" : value);
1058            hasNext = it.hasNext();
1059            if (hasNext) {
1060                buf.append(", ");
1061            }
1062        }
1063        buf.append(CollectionUtils.DEFAULT_TOSTRING_SUFFIX);
1064        return buf.toString();
1065    }
1066
1067    /**
1068     * Updates the node with a new value.
1069     * This implementation sets the value on the node.
1070     * Subclasses can override this to record the change.
1071     *
1072     * @param node  node to update
1073     * @param value  new value of the node
1074     */
1075    protected void updateNode(final Node<E> node, final E value) {
1076        node.setValue(value);
1077    }
1078
1079}