/** * Unlinks, or removes, a given {@code Node} from this LinkedList's structure. * * <p>This operation constitutes a structural modification. * * @param n The node to unlink. * @return The data previously contained by the given node. */ private E unlink(Node<E> n) { final E element = n.item; final Node<E> previous = n.previousLink; final Node<E> next = n.nextLink; if (previous == null) { first = next; } else { previous.nextLink = next; n.previousLink = null; } if (next == null) { last = previous; } else { next.previousLink = previous; n.nextLink = null; } n.item = null; size--; modCount++; return element; }
/** * Links the given element as the first link in the structure. In the case that the old first * element is {@code null}, the first and last link are made to refer to the same link. * * <p>This operation constitutes a structural modification. * * @param element The data for the new first link of the structure. */ private void linkFirst(E element) { final Node<E> oldFirst = first; final Node<E> newFirst = new Node<>(element, null, first); first = newFirst; if (oldFirst == null) { last = newFirst; } else { oldFirst.previousLink = newFirst; } size++; modCount++; }
/** * Removes all elements contained within this {@code LinkedList}. After this method call, {@link * #isEmpty()} should always return {@code true}. * * <p>This operation constitutes a structural modification. */ @Override public void clear() { Node<E> next; for (Node<E> n = first; n != null; n = next) { next = n.nextLink; n.item = null; n.previousLink = null; n.nextLink = null; } first = null; last = null; size = 0; modCount++; }
/** * Unlinks the last node in the structure, returning the data that was previously contained by it. * * <p>This operation constitutes a structural modification. * * @param l The last node to remove from this structure. * @return The data previously contained by the given node. */ private E unlinkLast(Node<E> l) { final E element = l.item; final Node<E> previous = l.previousLink; l.item = null; l.previousLink = null; last = previous; if (previous == null) { first = null; } else { previous.nextLink = null; } size--; modCount++; return element; }
/** * Unlinks the first node in the structure, returning the data that was previously contained by * it. * * <p>This operation constitutes a structural modification. * * @param f The first node to remove from this structure. * @return The data previously contained by the given node. */ private E unlinkFirst(Node<E> f) { final E element = f.item; final Node<E> next = f.nextLink; f.item = null; f.nextLink = null; first = next; if (next == null) { last = null; } else { next.previousLink = null; } size--; modCount++; return element; }
/** * Inserts into this {@code LinkedList} all elements contained within the given {@code Collection} * argument at the given index. This operation uses the iterator of the given collection, * therefore, care should be taken if the order of the elements that are being inserted must be * preserved. Finally, should the given collection be modified during the run of this method, the * resulting behavior is undefined. * * <p>This operation constitutes a structural modification. * * @param index The index * @param c The {@code Collection} containing the elements to to this {@code LinkedList}. * @return {@code true} if the add operation was successful, {@code false} otherwise. * @throws NullPointerException if the specified argument {@code c} is {@code null}. */ @Override @SuppressWarnings("unchecked") public boolean addAll(int index, Collection<? extends E> c) { Objects.requireNonNull(c, "Invalid null Collection!"); rangeCheckForAdd(index); Object[] elements = c.toArray(); int newElementCount = elements.length; if (newElementCount == 0) { return false; } Node<E> previous, succeeding; if (index == size) { succeeding = null; previous = last; } else { succeeding = nodeAt(index); previous = succeeding.previousLink; } for (Object obj : elements) { E element = (E) obj; Node<E> newNode = new Node<>(element, previous, null); if (previous == null) { first = newNode; } else { previous.nextLink = newNode; } previous = newNode; } if (succeeding == null) { last = previous; } else { previous.nextLink = succeeding; succeeding.previousLink = previous; } size += newElementCount; modCount++; return true; }