@Override @SuppressWarnings("unchecked") public <T> T[] toArray(T[] array) { // Extend the array if needed if (array.length < size) { final Class<?> componentType = array.getClass().getComponentType(); array = (T[]) Array.newInstance(componentType, size); } // Copy the values into the array int i = 0; for (Node<E> node = header.next; node != header; node = node.next, i++) { array[i] = (T) node.getValue(); } // Set the value after the last value to null if (array.length > size) { array[size] = null; } return array; }
/** * Adds a node to the cache, if the cache isn't full. * The node's contents are cleared to so they can be garbage collected. * * @param node the node to add to the cache */ protected void addNodeToCache(final Node<E> node) { if (isCacheFull()) { // don't cache the node. return; } // clear the node's contents and add it to the cache. final Node<E> nextCachedNode = firstCachedNode; node.previous = null; node.next = nextCachedNode; node.setValue(null); firstCachedNode = node; cacheSize++; }
/** * Creates a new node, either by reusing one from the cache or creating * a new one. * * @param value value of the new node * @return the newly created node */ @Override protected Node<E> createNode(final E value) { final Node<E> cachedNode = getNodeFromCache(); if (cachedNode == null) { return super.createNode(value); } cachedNode.setValue(value); return cachedNode; }
@Override public E previous() { checkModCount(); if (!hasPrevious()) { throw new NoSuchElementException("Already at start of list."); } next = next.previous; final E value = next.getValue(); current = next; nextIndex--; return value; }
public E removeFirst() { final Node<E> node = header.next; if (node == header) { throw new NoSuchElementException(); } final E oldValue = node.getValue(); removeNode(node); return oldValue; }
@Override public E set(final int index, final E value) { final Node<E> node = getNode(index, false); final E oldValue = node.getValue(); updateNode(node, value); return oldValue; }
@Override public int lastIndexOf(final Object value) { int i = size - 1; for (Node<E> node = header.previous; node != header; node = node.previous) { if (isEqualValue(node.getValue(), value)) { return i; } i--; } return -1; }
@Override public void set(final E obj) { checkModCount(); getLastNodeReturned().setValue(obj); }
@Override public E next() { checkModCount(); if (!hasNext()) { throw new NoSuchElementException("No element at index " + nextIndex + "."); } final E value = next.getValue(); current = next; next = next.next; nextIndex++; return value; }
public E removeLast() { final Node<E> node = header.previous; if (node == header) { throw new NoSuchElementException(); } final E oldValue = node.getValue(); removeNode(node); return oldValue; }
@Override public E get(final int index) { final Node<E> node = getNode(index, false); return node.getValue(); }
public E getLast() { final Node<E> node = header.previous; if (node == header) { throw new NoSuchElementException(); } return node.getValue(); }
public E getFirst() { final Node<E> node = header.next; if (node == header) { throw new NoSuchElementException(); } return node.getValue(); }
@Override public E remove(final int index) { final Node<E> node = getNode(index, false); final E oldValue = node.getValue(); removeNode(node); return oldValue; }
@Override public int indexOf(final Object value) { int i = 0; for (Node<E> node = header.next; node != header; node = node.next) { if (isEqualValue(node.getValue(), value)) { return i; } i++; } return -1; }
/** * Creates a new node with previous, next and element all set to null. * This implementation creates a new empty Node. * Subclasses can override this to create a different class. * * @return newly created node */ protected Node<E> createHeaderNode() { return new Node<>(); }
/** * Creates a new node with the specified properties. * This implementation creates a new Node with data. * Subclasses can override this to create a different class. * * @param value value of the new node * @return a new node containing the value */ protected Node<E> createNode(final E value) { return new Node<>(value); }
/** * Updates the node with a new value. * This implementation sets the value on the node. * Subclasses can override this to record the change. * * @param node node to update * @param value new value of the node */ protected void updateNode(final Node<E> node, final E value) { node.setValue(value); }
@Override public boolean remove(final Object value) { for (Node<E> node = header.next; node != header; node = node.next) { if (isEqualValue(node.getValue(), value)) { removeNode(node); return true; } } return false; }