AbstractLinkedList.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.  *
  41.  * @param <E> the type of elements in this list
  42.  * @since 3.0
  43.  * @deprecated use {@link AbstractLinkedListJava21} instead
  44.  */
  45. @Deprecated
  46. public abstract class AbstractLinkedList<E> implements List<E> {

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

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

  63.         /** The parent list */
  64.         protected final AbstractLinkedList<E> parent;

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

  70.         /**
  71.          * The index of {@link #next}.
  72.          */
  73.         protected int nextIndex;

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

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

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

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

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

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

  137.         @Override
  138.         public boolean hasNext() {
  139.             return next != parent.header;
  140.         }

  141.         @Override
  142.         public boolean hasPrevious() {
  143.             return next.previous != parent.header;
  144.         }

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

  157.         @Override
  158.         public int nextIndex() {
  159.             return nextIndex;
  160.         }

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

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

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

  193.         @Override
  194.         public void set(final E value) {
  195.             checkModCount();
  196.             getLastNodeReturned().setValue(value);
  197.         }

  198.     }

  199.     /**
  200.      * The sublist implementation for AbstractLinkedList.
  201.      *
  202.      * @param <E> the type of elements in this list.
  203.      */
  204.     protected static class LinkedSubList<E> extends AbstractList<E> {

  205.         /** The main list */
  206.         AbstractLinkedList<E> parent;

  207.         /** Offset from the main list */
  208.         int offset;

  209.         /** Sublist size */
  210.         int size;

  211.         /** Sublist modCount */
  212.         int expectedModCount;

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

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

  244.         @Override
  245.         public boolean addAll(final Collection<? extends E> coll) {
  246.             return addAll(size, coll);
  247.         }

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

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

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

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

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

  285.         @Override
  286.         public Iterator<E> iterator() {
  287.             checkModCount();
  288.             return parent.createSubListIterator(this);
  289.         }

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

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

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

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

  323.         @Override
  324.         public int size() {
  325.             checkModCount();
  326.             return size;
  327.         }

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

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

  339.         /** The sub list. */
  340.         protected final LinkedSubList<E> sub;

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

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

  357.         @Override
  358.         public boolean hasNext() {
  359.             return nextIndex() < sub.size;
  360.         }

  361.         @Override
  362.         public boolean hasPrevious() {
  363.             return previousIndex() >= 0;
  364.         }

  365.         @Override
  366.         public int nextIndex() {
  367.             return super.nextIndex() - sub.offset;
  368.         }

  369.         @Override
  370.         public void remove() {
  371.             super.remove();
  372.             sub.expectedModCount = parent.modCount;
  373.             sub.size--;
  374.         }
  375.     }

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

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

  392.         /**
  393.          * Constructs a new header node.
  394.          */
  395.         protected Node() {
  396.             previous = this;
  397.             next = this;
  398.         }

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

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

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

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

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

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

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

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

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

  480.     /** The size of the list */
  481.     transient int size;

  482.     /** Modification count for iterators */
  483.     transient int modCount;

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

  492.     /**
  493.      * Constructs a list copying data from the specified collection.
  494.      *
  495.      * @param coll  the collection to copy
  496.      */
  497.     protected AbstractLinkedList(final Collection<? extends E> coll) {
  498.         init();
  499.         addAll(coll);
  500.     }

  501.     @Override
  502.     public boolean add(final E value) {
  503.         addLast(value);
  504.         return true;
  505.     }

  506.     @Override
  507.     public void add(final int index, final E value) {
  508.         final Node<E> node = getNode(index, true);
  509.         addNodeBefore(node, value);
  510.     }

  511.     @Override
  512.     public boolean addAll(final Collection<? extends E> coll) {
  513.         return addAll(size, coll);
  514.     }

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

  523.     /**
  524.      * Adds an element at the beginning.
  525.      *
  526.      * @param e the element to beginning.
  527.      * @return true.
  528.      */
  529.     public boolean addFirst(final E e) {
  530.         addNodeAfter(header, e);
  531.         return true;
  532.     }

  533.     /**
  534.      * Adds an element at the end.
  535.      *
  536.      * @param e the element to add.
  537.      * @return true.
  538.      */
  539.     public boolean addLast(final E e) {
  540.         addNodeBefore(header, e);
  541.         return true;
  542.     }

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

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

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

  590.     @Override
  591.     public void clear() {
  592.         removeAllNodes();
  593.     }

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

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

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

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

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

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

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

  665.     /**
  666.      * Serializes the data held in this object to the stream specified.
  667.      * <p>
  668.      * The first serializable subclass must call this method from
  669.      * {@code writeObject}.
  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.      * Gets the first element.
  709.      *
  710.      * @return the first element.
  711.      */
  712.     public E getFirst() {
  713.         final Node<E> node = header.next;
  714.         if (node == header) {
  715.             throw new NoSuchElementException();
  716.         }
  717.         return node.getValue();
  718.     }

  719.     /**
  720.      * Gets the last element.
  721.      *
  722.      * @return the last element.
  723.      */
  724.     public E getLast() {
  725.         final Node<E> node = header.previous;
  726.         if (node == header) {
  727.             throw new NoSuchElementException();
  728.         }
  729.         return node.getValue();
  730.     }

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

  774.     @Override
  775.     public int hashCode() {
  776.         int hashCode = 1;
  777.         for (final E e : this) {
  778.             hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
  779.         }
  780.         return hashCode;
  781.     }

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

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

  802.     @Override
  803.     public boolean isEmpty() {
  804.         return size() == 0;
  805.     }

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

  818.     @Override
  819.     public Iterator<E> iterator() {
  820.         return listIterator();
  821.     }

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

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

  837.     @Override
  838.     public ListIterator<E> listIterator(final int fromIndex) {
  839.         return new LinkedListIterator<>(this, fromIndex);
  840.     }

  841.     @Override
  842.     public E remove(final int index) {
  843.         final Node<E> node = getNode(index, false);
  844.         final E oldValue = node.getValue();
  845.         removeNode(node);
  846.         return oldValue;
  847.     }

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

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

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

  888.     /**
  889.      * Removes the first element.
  890.      *
  891.      * @return The value removed.
  892.      */
  893.     public E removeFirst() {
  894.         final Node<E> node = header.next;
  895.         if (node == header) {
  896.             throw new NoSuchElementException();
  897.         }
  898.         final E oldValue = node.getValue();
  899.         removeNode(node);
  900.         return oldValue;
  901.     }

  902.     /**
  903.      * Removes the last element.
  904.      *
  905.      * @return The value removed.
  906.      */
  907.     public E removeLast() {
  908.         final Node<E> node = header.previous;
  909.         if (node == header) {
  910.             throw new NoSuchElementException();
  911.         }
  912.         final E oldValue = node.getValue();
  913.         removeNode(node);
  914.         return oldValue;
  915.     }

  916.     /**
  917.      * Removes the specified node from the list.
  918.      *
  919.      * @param node  the node to remove
  920.      * @throws NullPointerException if {@code node} is null
  921.      */
  922.     protected void removeNode(final Node<E> node) {
  923.         Objects.requireNonNull(node, "node");
  924.         node.previous.next = node.next;
  925.         node.next.previous = node.previous;
  926.         size--;
  927.         modCount++;
  928.     }

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

  950.     @Override
  951.     public E set(final int index, final E value) {
  952.         final Node<E> node = getNode(index, false);
  953.         final E oldValue = node.getValue();
  954.         updateNode(node, value);
  955.         return oldValue;
  956.     }

  957.     @Override
  958.     public int size() {
  959.         return size;
  960.     }

  961.     /**
  962.      * Gets a sublist of the main list.
  963.      *
  964.      * @param fromIndexInclusive  the index to start from
  965.      * @param toIndexExclusive  the index to end at
  966.      * @return the new sublist
  967.      */
  968.     @Override
  969.     public List<E> subList(final int fromIndexInclusive, final int toIndexExclusive) {
  970.         return new LinkedSubList<>(this, fromIndexInclusive, toIndexExclusive);
  971.     }

  972.     @Override
  973.     public Object[] toArray() {
  974.         return toArray(new Object[size]);
  975.     }

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

  995.     @Override
  996.     public String toString() {
  997.         if (isEmpty()) {
  998.             return "[]";
  999.         }
  1000.         final StringBuilder buf = new StringBuilder(16 * size());
  1001.         buf.append(CollectionUtils.DEFAULT_TOSTRING_PREFIX);

  1002.         final Iterator<E> it = iterator();
  1003.         boolean hasNext = it.hasNext();
  1004.         while (hasNext) {
  1005.             final Object value = it.next();
  1006.             buf.append(value == this ? "(this Collection)" : value);
  1007.             hasNext = it.hasNext();
  1008.             if (hasNext) {
  1009.                 buf.append(", ");
  1010.             }
  1011.         }
  1012.         buf.append(CollectionUtils.DEFAULT_TOSTRING_SUFFIX);
  1013.         return buf.toString();
  1014.     }

  1015.     /**
  1016.      * Updates the node with a new value.
  1017.      * This implementation sets the value on the node.
  1018.      * Subclasses can override this to record the change.
  1019.      *
  1020.      * @param node  node to update
  1021.      * @param value  new value of the node
  1022.      */
  1023.     protected void updateNode(final Node<E> node, final E value) {
  1024.         node.setValue(value);
  1025.     }

  1026. }