AbstractLinkedListJava21.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.collections4.list;

  18. import java.io.IOException;
  19. import java.io.ObjectInputStream;
  20. import java.io.ObjectOutputStream;
  21. import java.lang.reflect.Array;
  22. import java.util.AbstractList;
  23. import java.util.Collection;
  24. import java.util.ConcurrentModificationException;
  25. import java.util.Iterator;
  26. import java.util.List;
  27. import java.util.ListIterator;
  28. import java.util.NoSuchElementException;
  29. import java.util.Objects;

  30. import org.apache.commons.collections4.CollectionUtils;
  31. import org.apache.commons.collections4.OrderedIterator;

  32. /**
  33.  * An abstract implementation of a linked list which provides numerous points for
  34.  * subclasses to override.
  35.  * <p>
  36.  * Overridable methods are provided to change the storage node and to change how
  37.  * nodes are added to and removed. Hopefully, all you need for unusual subclasses
  38.  * is here.
  39.  * </p>
  40.  * <p>
  41.  * This is a copy of AbstractLinkedList, modified to be compatible with Java 21
  42.  * (see COLLECTIONS-842 for details).
  43.  * </p>
  44.  *
  45.  * @param <E> the type of elements in this list
  46.  * @see AbstractLinkedList
  47.  * @since 4.5.0-M3
  48.  */
  49. public abstract class AbstractLinkedListJava21<E> implements List<E> {

  50.     /*
  51.      * Implementation notes:
  52.      * - a standard circular doubly-linked list
  53.      * - a marker node is stored to mark the start and the end of the list
  54.      * - node creation and removal always occurs through createNode() and
  55.      *   removeNode().
  56.      * - a modification count is kept, with the same semantics as
  57.      * {@link java.util.LinkedList}.
  58.      * - respects {@link AbstractList#modCount}
  59.      */

  60.     /**
  61.      * A list iterator over the linked list.
  62.      *
  63.      * @param <E> the type of elements in this iterator.
  64.      */
  65.     protected static class LinkedListIterator<E> implements ListIterator<E>, OrderedIterator<E> {

  66.         /** The parent list */
  67.         protected final AbstractLinkedListJava21<E> parent;

  68.         /**
  69.          * The node that will be returned by {@link #next()}. If this is equal
  70.          * to {@link AbstractLinkedListJava21#header} then there are no more values to return.
  71.          */
  72.         protected Node<E> next;

  73.         /**
  74.          * The index of {@link #next}.
  75.          */
  76.         protected int nextIndex;

  77.         /**
  78.          * The last node that was returned by {@link #next()} or {@link
  79.          * #previous()}. Set to {@code null} if {@link #next()} or {@link
  80.          * #previous()} haven't been called, or if the node has been removed
  81.          * with {@link #remove()} or a new node added with {@link #add(Object)}.
  82.          * Should be accessed through {@link #getLastNodeReturned()} to enforce
  83.          * this behavior.
  84.          */
  85.         protected Node<E> current;

  86.         /**
  87.          * The modification count that the list is expected to have. If the list
  88.          * doesn't have this count, then a
  89.          * {@link java.util.ConcurrentModificationException} may be thrown by
  90.          * the operations.
  91.          */
  92.         protected int expectedModCount;

  93.         /**
  94.          * Create a ListIterator for a list.
  95.          *
  96.          * @param parent  the parent list
  97.          * @param fromIndex  the index to start at
  98.          * @throws IndexOutOfBoundsException if fromIndex is less than 0 or greater than the size of the list
  99.          */
  100.         protected LinkedListIterator(final AbstractLinkedListJava21<E> parent, final int fromIndex)
  101.                 throws IndexOutOfBoundsException {
  102.             this.parent = parent;
  103.             this.expectedModCount = parent.modCount;
  104.             this.next = parent.getNode(fromIndex, true);
  105.             this.nextIndex = fromIndex;
  106.         }

  107.         @Override
  108.         public void add(final E obj) {
  109.             checkModCount();
  110.             parent.addNodeBefore(next, obj);
  111.             current = null;
  112.             nextIndex++;
  113.             expectedModCount++;
  114.         }

  115.         /**
  116.          * Checks the modification count of the list is the value that this
  117.          * object expects.
  118.          *
  119.          * @throws ConcurrentModificationException If the list's modification
  120.          * count isn't the value that was expected.
  121.          */
  122.         protected void checkModCount() {
  123.             if (parent.modCount != expectedModCount) {
  124.                 throw new ConcurrentModificationException();
  125.             }
  126.         }

  127.         /**
  128.          * Gets the last node returned.
  129.          *
  130.          * @return the last node returned
  131.          * @throws IllegalStateException If {@link #next()} or {@link #previous()} haven't been called,
  132.          * or if the node has been removed with {@link #remove()} or a new node added with {@link #add(Object)}.
  133.          */
  134.         protected Node<E> getLastNodeReturned() throws IllegalStateException {
  135.             if (current == null) {
  136.                 throw new IllegalStateException();
  137.             }
  138.             return current;
  139.         }

  140.         @Override
  141.         public boolean hasNext() {
  142.             return next != parent.header;
  143.         }

  144.         @Override
  145.         public boolean hasPrevious() {
  146.             return next.previous != parent.header;
  147.         }

  148.         @Override
  149.         public E next() {
  150.             checkModCount();
  151.             if (!hasNext()) {
  152.                 throw new NoSuchElementException("No element at index " + nextIndex + ".");
  153.             }
  154.             final E value = next.getValue();
  155.             current = next;
  156.             next = next.next;
  157.             nextIndex++;
  158.             return value;
  159.         }

  160.         @Override
  161.         public int nextIndex() {
  162.             return nextIndex;
  163.         }

  164.         @Override
  165.         public E previous() {
  166.             checkModCount();
  167.             if (!hasPrevious()) {
  168.                 throw new NoSuchElementException("Already at start of list.");
  169.             }
  170.             next = next.previous;
  171.             final E value = next.getValue();
  172.             current = next;
  173.             nextIndex--;
  174.             return value;
  175.         }

  176.         @Override
  177.         public int previousIndex() {
  178.             // not normally overridden, as relative to nextIndex()
  179.             return nextIndex() - 1;
  180.         }

  181.         @Override
  182.         public void remove() {
  183.             checkModCount();
  184.             if (current == next) {
  185.                 // remove() following previous()
  186.                 next = next.next;
  187.                 parent.removeNode(getLastNodeReturned());
  188.             } else {
  189.                 // remove() following next()
  190.                 parent.removeNode(getLastNodeReturned());
  191.                 nextIndex--;
  192.             }
  193.             current = null;
  194.             expectedModCount++;
  195.         }

  196.         @Override
  197.         public void set(final E obj) {
  198.             checkModCount();
  199.             getLastNodeReturned().setValue(obj);
  200.         }

  201.     }

  202.     /**
  203.      * The sublist implementation for AbstractLinkedListJava21.
  204.      *
  205.      * @param <E> the type of elements in this list.
  206.      */
  207.     protected static class LinkedSubList<E> extends AbstractList<E> {
  208.         /** The main list */
  209.         AbstractLinkedListJava21<E> parent;
  210.         /** Offset from the main list */
  211.         int offset;
  212.         /** Sublist size */
  213.         int size;
  214.         /** Sublist modCount */
  215.         int expectedModCount;

  216.         /**
  217.          * Constructs a new instance.
  218.          *
  219.          * @param parent The parent AbstractLinkedList.
  220.          * @param fromIndex An index greater or equal to 0 and less than {@code toIndex}.
  221.          * @param toIndex An index greater than {@code fromIndex}.
  222.          */
  223.         protected LinkedSubList(final AbstractLinkedListJava21<E> parent, final int fromIndex, final int toIndex) {
  224.             if (fromIndex < 0) {
  225.                 throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
  226.             }
  227.             if (toIndex > parent.size()) {
  228.                 throw new IndexOutOfBoundsException("toIndex = " + toIndex);
  229.             }
  230.             if (fromIndex > toIndex) {
  231.                 throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
  232.             }
  233.             this.parent = parent;
  234.             this.offset = fromIndex;
  235.             this.size = toIndex - fromIndex;
  236.             this.expectedModCount = parent.modCount;
  237.         }

  238.         @Override
  239.         public void add(final int index, final E obj) {
  240.             rangeCheck(index, size + 1);
  241.             checkModCount();
  242.             parent.add(index + offset, obj);
  243.             expectedModCount = parent.modCount;
  244.             size++;
  245.             modCount++;
  246.         }

  247.         @Override
  248.         public boolean addAll(final Collection<? extends E> coll) {
  249.             return addAll(size, coll);
  250.         }

  251.         @Override
  252.         public boolean addAll(final int index, final Collection<? extends E> coll) {
  253.             rangeCheck(index, size + 1);
  254.             final int cSize = coll.size();
  255.             if (cSize == 0) {
  256.                 return false;
  257.             }

  258.             checkModCount();
  259.             parent.addAll(offset + index, coll);
  260.             expectedModCount = parent.modCount;
  261.             size += cSize;
  262.             modCount++;
  263.             return true;
  264.         }

  265.         /**
  266.          * Throws a {@link ConcurrentModificationException} if this instance fails its concurrency check.
  267.          */
  268.         protected void checkModCount() {
  269.             if (parent.modCount != expectedModCount) {
  270.                 throw new ConcurrentModificationException();
  271.             }
  272.         }

  273.         @Override
  274.         public void clear() {
  275.             checkModCount();
  276.             final Iterator<E> it = iterator();
  277.             while (it.hasNext()) {
  278.                 it.next();
  279.                 it.remove();
  280.             }
  281.         }

  282.         @Override
  283.         public E get(final int index) {
  284.             rangeCheck(index, size);
  285.             checkModCount();
  286.             return parent.get(index + offset);
  287.         }

  288.         @Override
  289.         public Iterator<E> iterator() {
  290.             checkModCount();
  291.             return parent.createSubListIterator(this);
  292.         }

  293.         @Override
  294.         public ListIterator<E> listIterator(final int index) {
  295.             rangeCheck(index, size + 1);
  296.             checkModCount();
  297.             return parent.createSubListListIterator(this, index);
  298.         }

  299.         /**
  300.          * Throws an {@link IndexOutOfBoundsException} if the given indices are out of bounds.
  301.          *
  302.          * @param index lower index.
  303.          * @param beyond upper index.
  304.          */
  305.         protected void rangeCheck(final int index, final int beyond) {
  306.             if (index < 0 || index >= beyond) {
  307.                 throw new IndexOutOfBoundsException("Index '" + index + "' out of bounds for size '" + size + "'");
  308.             }
  309.         }

  310.         @Override
  311.         public E remove(final int index) {
  312.             rangeCheck(index, size);
  313.             checkModCount();
  314.             final E result = parent.remove(index + offset);
  315.             expectedModCount = parent.modCount;
  316.             size--;
  317.             modCount++;
  318.             return result;
  319.         }

  320.         @Override
  321.         public E set(final int index, final E obj) {
  322.             rangeCheck(index, size);
  323.             checkModCount();
  324.             return parent.set(index + offset, obj);
  325.         }

  326.         @Override
  327.         public int size() {
  328.             checkModCount();
  329.             return size;
  330.         }

  331.         @Override
  332.         public List<E> subList(final int fromIndexInclusive, final int toIndexExclusive) {
  333.             return new LinkedSubList<>(parent, fromIndexInclusive + offset, toIndexExclusive + offset);
  334.         }
  335.     }

  336.     /**
  337.      * A list iterator over the linked sub list.
  338.      *
  339.      * @param <E> the type of elements in this iterator.
  340.      */
  341.     protected static class LinkedSubListIterator<E> extends LinkedListIterator<E> {

  342.         /** The sub list */
  343.         protected final LinkedSubList<E> sub;

  344.         /**
  345.          * Constructs a new instance.
  346.          *
  347.          * @param sub The sub-list.
  348.          * @param startIndex The starting index.
  349.          */
  350.         protected LinkedSubListIterator(final LinkedSubList<E> sub, final int startIndex) {
  351.             super(sub.parent, startIndex + sub.offset);
  352.             this.sub = sub;
  353.         }

  354.         @Override
  355.         public void add(final E obj) {
  356.             super.add(obj);
  357.             sub.expectedModCount = parent.modCount;
  358.             sub.size++;
  359.         }

  360.         @Override
  361.         public boolean hasNext() {
  362.             return nextIndex() < sub.size;
  363.         }

  364.         @Override
  365.         public boolean hasPrevious() {
  366.             return previousIndex() >= 0;
  367.         }

  368.         @Override
  369.         public int nextIndex() {
  370.             return super.nextIndex() - sub.offset;
  371.         }

  372.         @Override
  373.         public void remove() {
  374.             super.remove();
  375.             sub.expectedModCount = parent.modCount;
  376.             sub.size--;
  377.         }
  378.     }

  379.     /**
  380.      * A node within the linked list.
  381.      * <p>
  382.      * From Commons Collections 3.1, all access to the {@code value} property
  383.      * is via the methods on this class.
  384.      * </p>
  385.      *
  386.      * @param <E> the type of the node value.
  387.      */
  388.     protected static class Node<E> {

  389.         /** A pointer to the node before this node */
  390.         protected Node<E> previous;
  391.         /** A pointer to the node after this node */
  392.         protected Node<E> next;
  393.         /** The object contained within this node */
  394.         protected E value;

  395.         /**
  396.          * Constructs a new header node.
  397.          */
  398.         protected Node() {
  399.             previous = this;
  400.             next = this;
  401.         }

  402.         /**
  403.          * Constructs a new node.
  404.          *
  405.          * @param value  the value to store
  406.          */
  407.         protected Node(final E value) {
  408.             this.value = value;
  409.         }

  410.         /**
  411.          * Constructs a new node.
  412.          *
  413.          * @param previous  the previous node in the list
  414.          * @param next  the next node in the list
  415.          * @param value  the value to store
  416.          */
  417.         protected Node(final Node<E> previous, final Node<E> next, final E value) {
  418.             this.previous = previous;
  419.             this.next = next;
  420.             this.value = value;
  421.         }

  422.         /**
  423.          * Gets the next node.
  424.          *
  425.          * @return the next node
  426.          * @since 3.1
  427.          */
  428.         protected Node<E> getNextNode() {
  429.             return next;
  430.         }

  431.         /**
  432.          * Gets the previous node.
  433.          *
  434.          * @return the previous node
  435.          * @since 3.1
  436.          */
  437.         protected Node<E> getPreviousNode() {
  438.             return previous;
  439.         }

  440.         /**
  441.          * Gets the value of the node.
  442.          *
  443.          * @return the value
  444.          * @since 3.1
  445.          */
  446.         protected E getValue() {
  447.             return value;
  448.         }

  449.         /**
  450.          * Sets the next node.
  451.          *
  452.          * @param next  the next node
  453.          * @since 3.1
  454.          */
  455.         protected void setNextNode(final Node<E> next) {
  456.             this.next = next;
  457.         }

  458.         /**
  459.          * Sets the previous node.
  460.          *
  461.          * @param previous  the previous node
  462.          * @since 3.1
  463.          */
  464.         protected void setPreviousNode(final Node<E> previous) {
  465.             this.previous = previous;
  466.         }

  467.         /**
  468.          * Sets the value of the node.
  469.          *
  470.          * @param value  the value
  471.          * @since 3.1
  472.          */
  473.         protected void setValue(final E value) {
  474.             this.value = value;
  475.         }
  476.     }

  477.     /**
  478.      * A {@link Node} which indicates the start and end of the list and does not
  479.      * hold a value. The value of {@code next} is the first item in the
  480.      * list. The value of {@code previous} is the last item in the list.
  481.      */
  482.     transient Node<E> header;

  483.     /** The size of the list */
  484.     transient int size;

  485.     /** Modification count for iterators */
  486.     transient int modCount;

  487.     /**
  488.      * Constructor that does nothing (intended for deserialization).
  489.      * <p>
  490.      * If this constructor is used by a serializable subclass then the init()
  491.      * method must be called.
  492.      * </p>
  493.      */
  494.     protected AbstractLinkedListJava21() {
  495.     }

  496.     /**
  497.      * Constructs a list copying data from the specified collection.
  498.      *
  499.      * @param coll  the collection to copy
  500.      */
  501.     protected AbstractLinkedListJava21(final Collection<? extends E> coll) {
  502.         init();
  503.         addAll(coll);
  504.     }

  505.     @Override
  506.     public boolean add(final E value) {
  507.         addLast(value);
  508.         return true;
  509.     }

  510.     @Override
  511.     public void add(final int index, final E value) {
  512.         final Node<E> node = getNode(index, true);
  513.         addNodeBefore(node, value);
  514.     }

  515.     @Override
  516.     public boolean addAll(final Collection<? extends E> coll) {
  517.         return addAll(size, coll);
  518.     }

  519.     @Override
  520.     public boolean addAll(final int index, final Collection<? extends E> coll) {
  521.         final Node<E> node = getNode(index, true);
  522.         for (final E e : coll) {
  523.             addNodeBefore(node, e);
  524.         }
  525.         return true;
  526.     }

  527.     /**
  528.      * {@inheritDoc}
  529.      */
  530.     public void addFirst(final E o) {
  531.         addNodeAfter(header, o);
  532.     }

  533.     /**
  534.      * {@inheritDoc}
  535.      */
  536.     public void addLast(final E o) {
  537.         addNodeBefore(header, o);
  538.     }

  539.     /**
  540.      * Inserts a new node into the list.
  541.      *
  542.      * @param nodeToInsert  new node to insert
  543.      * @param insertBeforeNode  node to insert before
  544.      * @throws NullPointerException if either node is null
  545.      */
  546.     protected void addNode(final Node<E> nodeToInsert, final Node<E> insertBeforeNode) {
  547.         Objects.requireNonNull(nodeToInsert, "nodeToInsert");
  548.         Objects.requireNonNull(insertBeforeNode, "insertBeforeNode");
  549.         nodeToInsert.next = insertBeforeNode;
  550.         nodeToInsert.previous = insertBeforeNode.previous;
  551.         insertBeforeNode.previous.next = nodeToInsert;
  552.         insertBeforeNode.previous = nodeToInsert;
  553.         size++;
  554.         modCount++;
  555.     }

  556.     /**
  557.      * Creates a new node with the specified object as its
  558.      * {@code value} and inserts it after {@code node}.
  559.      * <p>
  560.      * This implementation uses {@link #createNode(Object)} and
  561.      * {@link #addNode(AbstractLinkedListJava21.Node,AbstractLinkedListJava21.Node)}.
  562.      * </p>
  563.      *
  564.      * @param node  node to insert after
  565.      * @param value  value of the newly added node
  566.      * @throws NullPointerException if {@code node} is null
  567.      */
  568.     protected void addNodeAfter(final Node<E> node, final E value) {
  569.         final Node<E> newNode = createNode(value);
  570.         addNode(newNode, node.next);
  571.     }

  572.     /**
  573.      * Creates a new node with the specified object as its
  574.      * {@code value} and inserts it before {@code node}.
  575.      * <p>
  576.      * This implementation uses {@link #createNode(Object)} and
  577.      * {@link #addNode(AbstractLinkedListJava21.Node,AbstractLinkedListJava21.Node)}.
  578.      * </p>
  579.      *
  580.      * @param node  node to insert before
  581.      * @param value  value of the newly added node
  582.      * @throws NullPointerException if {@code node} is null
  583.      */
  584.     protected void addNodeBefore(final Node<E> node, final E value) {
  585.         final Node<E> newNode = createNode(value);
  586.         addNode(newNode, node);
  587.     }

  588.     @Override
  589.     public void clear() {
  590.         removeAllNodes();
  591.     }

  592.     @Override
  593.     public boolean contains(final Object value) {
  594.         return indexOf(value) != -1;
  595.     }

  596.     @Override
  597.     public boolean containsAll(final Collection<?> coll) {
  598.         for (final Object o : coll) {
  599.             if (!contains(o)) {
  600.                 return false;
  601.             }
  602.         }
  603.         return true;
  604.     }

  605.     /**
  606.      * Creates a new node with previous, next and element all set to null.
  607.      * This implementation creates a new empty Node.
  608.      * Subclasses can override this to create a different class.
  609.      *
  610.      * @return  newly created node
  611.      */
  612.     protected Node<E> createHeaderNode() {
  613.         return new Node<>();
  614.     }

  615.     /**
  616.      * Creates a new node with the specified properties.
  617.      * This implementation creates a new Node with data.
  618.      * Subclasses can override this to create a different class.
  619.      *
  620.      * @param value  value of the new node
  621.      * @return a new node containing the value
  622.      */
  623.     protected Node<E> createNode(final E value) {
  624.         return new Node<>(value);
  625.     }

  626.     /**
  627.      * Creates an iterator for the sublist.
  628.      *
  629.      * @param subList  the sublist to get an iterator for
  630.      * @return a new iterator on the given sublist
  631.      */
  632.     protected Iterator<E> createSubListIterator(final LinkedSubList<E> subList) {
  633.         return createSubListListIterator(subList, 0);
  634.     }

  635.     /**
  636.      * Creates a list iterator for the sublist.
  637.      *
  638.      * @param subList  the sublist to get an iterator for
  639.      * @param fromIndex  the index to start from, relative to the sublist
  640.      * @return a new list iterator on the given sublist
  641.      */
  642.     protected ListIterator<E> createSubListListIterator(final LinkedSubList<E> subList, final int fromIndex) {
  643.         return new LinkedSubListIterator<>(subList, fromIndex);
  644.     }

  645.     /**
  646.      * Deserializes the data held in this object to the stream specified.
  647.      * <p>
  648.      * The first serializable subclass must call this method from
  649.      * {@code readObject}.
  650.      * </p>
  651.      *
  652.      * @param inputStream  the stream to read the object from
  653.      * @throws IOException  if any error occurs while reading from the stream
  654.      * @throws ClassNotFoundException  if a class read from the stream cannot be loaded
  655.      */
  656.     @SuppressWarnings("unchecked")
  657.     protected void doReadObject(final ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
  658.         init();
  659.         final int size = inputStream.readInt();
  660.         for (int i = 0; i < size; i++) {
  661.             add((E) inputStream.readObject());
  662.         }
  663.     }

  664.     /**
  665.      * Serializes the data held in this object to the stream specified.
  666.      * <p>
  667.      * The first serializable subclass must call this method from
  668.      * {@code writeObject}.
  669.      * </p>
  670.      *
  671.      * @param outputStream  the stream to write the object to
  672.      * @throws IOException  if anything goes wrong
  673.      */
  674.     protected void doWriteObject(final ObjectOutputStream outputStream) throws IOException {
  675.         // Write the size so we know how many nodes to read back
  676.         outputStream.writeInt(size());
  677.         for (final E e : this) {
  678.             outputStream.writeObject(e);
  679.         }
  680.     }

  681.     @Override
  682.     public boolean equals(final Object obj) {
  683.         if (obj == this) {
  684.             return true;
  685.         }
  686.         if (!(obj instanceof List)) {
  687.             return false;
  688.         }
  689.         final List<?> other = (List<?>) obj;
  690.         if (other.size() != size()) {
  691.             return false;
  692.         }
  693.         final ListIterator<?> it1 = listIterator();
  694.         final ListIterator<?> it2 = other.listIterator();
  695.         while (it1.hasNext() && it2.hasNext()) {
  696.             if (!Objects.equals(it1.next(), it2.next())) {
  697.                 return false;
  698.             }
  699.         }
  700.         return !(it1.hasNext() || it2.hasNext());
  701.     }

  702.     @Override
  703.     public E get(final int index) {
  704.         final Node<E> node = getNode(index, false);
  705.         return node.getValue();
  706.     }

  707.     /**
  708.      * {@inheritDoc}
  709.      */
  710.     public E getFirst() {
  711.         final Node<E> node = header.next;
  712.         if (node == header) {
  713.             throw new NoSuchElementException();
  714.         }
  715.         return node.getValue();
  716.     }

  717.     /**
  718.      * {@inheritDoc}
  719.      */
  720.     public E getLast() {
  721.         final Node<E> node = header.previous;
  722.         if (node == header) {
  723.             throw new NoSuchElementException();
  724.         }
  725.         return node.getValue();
  726.     }

  727.     /**
  728.      * Gets the node at a particular index.
  729.      *
  730.      * @param index  the index, starting from 0
  731.      * @param endMarkerAllowed  whether or not the end marker can be returned if
  732.      * startIndex is set to the list's size
  733.      * @return the node at the given index
  734.      * @throws IndexOutOfBoundsException if the index is less than 0; equal to
  735.      * the size of the list and endMakerAllowed is false; or greater than the
  736.      * size of the list
  737.      */
  738.     protected Node<E> getNode(final int index, final boolean endMarkerAllowed) throws IndexOutOfBoundsException {
  739.         // Check the index is within the bounds
  740.         if (index < 0) {
  741.             throw new IndexOutOfBoundsException("Couldn't get the node: " +
  742.                     "index (" + index + ") less than zero.");
  743.         }
  744.         if (!endMarkerAllowed && index == size) {
  745.             throw new IndexOutOfBoundsException("Couldn't get the node: " +
  746.                     "index (" + index + ") is the size of the list.");
  747.         }
  748.         if (index > size) {
  749.             throw new IndexOutOfBoundsException("Couldn't get the node: " +
  750.                     "index (" + index + ") greater than the size of the " +
  751.                     "list (" + size + ").");
  752.         }
  753.         // Search the list and get the node
  754.         Node<E> node;
  755.         if (index < size / 2) {
  756.             // Search forwards
  757.             node = header.next;
  758.             for (int currentIndex = 0; currentIndex < index; currentIndex++) {
  759.                 node = node.next;
  760.             }
  761.         } else {
  762.             // Search backwards
  763.             node = header;
  764.             for (int currentIndex = size; currentIndex > index; currentIndex--) {
  765.                 node = node.previous;
  766.             }
  767.         }
  768.         return node;
  769.     }

  770.     @Override
  771.     public int hashCode() {
  772.         int hashCode = 1;
  773.         for (final E e : this) {
  774.             hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
  775.         }
  776.         return hashCode;
  777.     }

  778.     @Override
  779.     public int indexOf(final Object value) {
  780.         int i = 0;
  781.         for (Node<E> node = header.next; node != header; node = node.next) {
  782.             if (isEqualValue(node.getValue(), value)) {
  783.                 return i;
  784.             }
  785.             i++;
  786.         }
  787.         return CollectionUtils.INDEX_NOT_FOUND;
  788.     }

  789.     /**
  790.      * The equivalent of a default constructor, broken out so it can be called
  791.      * by any constructor and by {@code readObject}.
  792.      * Subclasses which override this method should make sure they call super,
  793.      * so the list is initialized properly.
  794.      */
  795.     protected void init() {
  796.         header = createHeaderNode();
  797.     }

  798.     @Override
  799.     public boolean isEmpty() {
  800.         return size() == 0;
  801.     }

  802.     /**
  803.      * Compares two values for equals.
  804.      * This implementation uses the equals method.
  805.      * Subclasses can override this to match differently.
  806.      *
  807.      * @param value1  the first value to compare, may be null
  808.      * @param value2  the second value to compare, may be null
  809.      * @return true if equal
  810.      */
  811.     protected boolean isEqualValue(final Object value1, final Object value2) {
  812.         return Objects.equals(value1, value2);
  813.     }

  814.     @Override
  815.     public Iterator<E> iterator() {
  816.         return listIterator();
  817.     }

  818.     @Override
  819.     public int lastIndexOf(final Object value) {
  820.         int i = size - 1;
  821.         for (Node<E> node = header.previous; node != header; node = node.previous) {
  822.             if (isEqualValue(node.getValue(), value)) {
  823.                 return i;
  824.             }
  825.             i--;
  826.         }
  827.         return CollectionUtils.INDEX_NOT_FOUND;
  828.     }

  829.     @Override
  830.     public ListIterator<E> listIterator() {
  831.         return new LinkedListIterator<>(this, 0);
  832.     }

  833.     @Override
  834.     public ListIterator<E> listIterator(final int fromIndex) {
  835.         return new LinkedListIterator<>(this, fromIndex);
  836.     }

  837.     @Override
  838.     public E remove(final int index) {
  839.         final Node<E> node = getNode(index, false);
  840.         final E oldValue = node.getValue();
  841.         removeNode(node);
  842.         return oldValue;
  843.     }

  844.     @Override
  845.     public boolean remove(final Object value) {
  846.         for (Node<E> node = header.next; node != header; node = node.next) {
  847.             if (isEqualValue(node.getValue(), value)) {
  848.                 removeNode(node);
  849.                 return true;
  850.             }
  851.         }
  852.         return false;
  853.     }

  854.     /**
  855.      * {@inheritDoc}
  856.      * <p>
  857.      * This implementation iterates over the elements of this list, checking each element in
  858.      * turn to see if it's contained in {@code coll}. If it's contained, it's removed
  859.      * from this list. As a consequence, it is advised to use a collection type for
  860.      * {@code coll} that provides a fast (for example O(1)) implementation of
  861.      * {@link Collection#contains(Object)}.
  862.      * </p>
  863.      */
  864.     @Override
  865.     public boolean removeAll(final Collection<?> coll) {
  866.         boolean modified = false;
  867.         final Iterator<E> it = iterator();
  868.         while (it.hasNext()) {
  869.             if (coll.contains(it.next())) {
  870.                 it.remove();
  871.                 modified = true;
  872.             }
  873.         }
  874.         return modified;
  875.     }

  876.     /**
  877.      * Removes all nodes by resetting the circular list marker.
  878.      */
  879.     protected void removeAllNodes() {
  880.         header.next = header;
  881.         header.previous = header;
  882.         size = 0;
  883.         modCount++;
  884.     }

  885.     /**
  886.      * {@inheritDoc}
  887.      */
  888.     public E removeFirst() {
  889.         final Node<E> node = header.next;
  890.         if (node == header) {
  891.             throw new NoSuchElementException();
  892.         }
  893.         final E oldValue = node.getValue();
  894.         removeNode(node);
  895.         return oldValue;
  896.     }

  897.     /**
  898.      * {@inheritDoc}
  899.      */
  900.     public E removeLast() {
  901.         final Node<E> node = header.previous;
  902.         if (node == header) {
  903.             throw new NoSuchElementException();
  904.         }
  905.         final E oldValue = node.getValue();
  906.         removeNode(node);
  907.         return oldValue;
  908.     }

  909.     /**
  910.      * Removes the specified node from the list.
  911.      *
  912.      * @param node  the node to remove
  913.      * @throws NullPointerException if {@code node} is null
  914.      */
  915.     protected void removeNode(final Node<E> node) {
  916.         Objects.requireNonNull(node, "node");
  917.         node.previous.next = node.next;
  918.         node.next.previous = node.previous;
  919.         size--;
  920.         modCount++;
  921.     }

  922.     /**
  923.      * {@inheritDoc}
  924.      * <p>
  925.      * This implementation iterates over the elements of this list, checking each element in
  926.      * turn to see if it's contained in {@code coll}. If it's not contained, it's removed
  927.      * from this list. As a consequence, it is advised to use a collection type for
  928.      * {@code coll} that provides a fast (for example O(1)) implementation of
  929.      * {@link Collection#contains(Object)}.
  930.      * </p>
  931.      */
  932.     @Override
  933.     public boolean retainAll(final Collection<?> coll) {
  934.         boolean modified = false;
  935.         final Iterator<E> it = iterator();
  936.         while (it.hasNext()) {
  937.             if (!coll.contains(it.next())) {
  938.                 it.remove();
  939.                 modified = true;
  940.             }
  941.         }
  942.         return modified;
  943.     }

  944.     @Override
  945.     public E set(final int index, final E value) {
  946.         final Node<E> node = getNode(index, false);
  947.         final E oldValue = node.getValue();
  948.         updateNode(node, value);
  949.         return oldValue;
  950.     }

  951.     @Override
  952.     public int size() {
  953.         return size;
  954.     }

  955.     /**
  956.      * Gets a sublist of the main list.
  957.      *
  958.      * @param fromIndexInclusive  the index to start from
  959.      * @param toIndexExclusive  the index to end at
  960.      * @return the new sublist
  961.      */
  962.     @Override
  963.     public List<E> subList(final int fromIndexInclusive, final int toIndexExclusive) {
  964.         return new LinkedSubList<>(this, fromIndexInclusive, toIndexExclusive);
  965.     }

  966.     @Override
  967.     public Object[] toArray() {
  968.         return toArray(new Object[size]);
  969.     }

  970.     @Override
  971.     @SuppressWarnings("unchecked")
  972.     public <T> T[] toArray(T[] array) {
  973.         // Extend the array if needed
  974.         if (array.length < size) {
  975.             final Class<?> componentType = array.getClass().getComponentType();
  976.             array = (T[]) Array.newInstance(componentType, size);
  977.         }
  978.         // Copy the values into the array
  979.         int i = 0;
  980.         for (Node<E> node = header.next; node != header; node = node.next, i++) {
  981.             array[i] = (T) node.getValue();
  982.         }
  983.         // Set the value after the last value to null
  984.         if (array.length > size) {
  985.             array[size] = null;
  986.         }
  987.         return array;
  988.     }

  989.     @Override
  990.     public String toString() {
  991.         if (isEmpty()) {
  992.             return "[]";
  993.         }
  994.         final StringBuilder buf = new StringBuilder(16 * size());
  995.         buf.append(CollectionUtils.DEFAULT_TOSTRING_PREFIX);

  996.         final Iterator<E> it = iterator();
  997.         boolean hasNext = it.hasNext();
  998.         while (hasNext) {
  999.             final Object value = it.next();
  1000.             buf.append(value == this ? "(this Collection)" : value);
  1001.             hasNext = it.hasNext();
  1002.             if (hasNext) {
  1003.                 buf.append(", ");
  1004.             }
  1005.         }
  1006.         buf.append(CollectionUtils.DEFAULT_TOSTRING_SUFFIX);
  1007.         return buf.toString();
  1008.     }

  1009.     /**
  1010.      * Updates the node with a new value.
  1011.      * This implementation sets the value on the node.
  1012.      * Subclasses can override this to record the change.
  1013.      *
  1014.      * @param node  node to update
  1015.      * @param value  new value of the node
  1016.      */
  1017.     protected void updateNode(final Node<E> node, final E value) {
  1018.         node.setValue(value);
  1019.     }

  1020. }