/** * Returns the successor of p, or the first node if p.next has been * linked to self, which will only be true if traversing with a * stale pointer that is now off the list. */ final Node<E> succ(Node<E> p) { // TODO: should we skip deleted nodes here? Node<E> q = p.next; return (p == q) ? first() : q; }
public E peekFirst() { for (Node<E> p = first(); p != null; p = succ(p)) { E item = p.item; if (item != null) return item; } return null; }
/** * Returns {@code true} if this deque contains at least one * element {@code e} such that {@code o.equals(e)}. * * @param o element whose presence in this deque is to be tested * @return {@code true} if this deque contains the specified element */ public boolean contains(Object o) { if (o == null) return false; for (Node<E> p = first(); p != null; p = succ(p)) { E item = p.item; if (item != null && o.equals(item)) return true; } return false; }
/** * Creates an array list and fills it with elements of this list. * Used by toArray. * * @return the arrayList */ private ArrayList<E> toArrayList() { ArrayList<E> list = new ArrayList<E>(); for (Node<E> p = first(); p != null; p = succ(p)) { E item = p.item; if (item != null) list.add(item); } return list; }
/** * Saves the state to a stream (that is, serializes it). * * @serialData All of the elements (each an {@code E}) in * the proper order, followed by a null * @param s the stream */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { // Write out any hidden stuff s.defaultWriteObject(); // Write out all elements in the proper order. for (Node<E> p = first(); p != null; p = succ(p)) { E item = p.item; if (item != null) s.writeObject(item); } // Use trailing null as sentinel s.writeObject(null); }
/** * Returns the number of elements in this deque. If this deque * contains more than {@code Integer.MAX_VALUE} elements, it * returns {@code Integer.MAX_VALUE}. * * <p>Beware that, unlike in most collections, this method is * <em>NOT</em> a constant-time operation. Because of the * asynchronous nature of these deques, determining the current * number of elements requires traversing them all to count them. * Additionally, it is possible for the size to change during * execution of this method, in which case the returned result * will be inaccurate. Thus, this method is typically not very * useful in concurrent applications. * * @return the number of elements in this deque */ public int size() { int count = 0; for (Node<E> p = first(); p != null; p = succ(p)) if (p.item != null) // Collection.size() spec says to max out if (++count == Integer.MAX_VALUE) break; return count; }
public E pollFirst() { for (Node<E> p = first(); p != null; p = succ(p)) { E item = p.item; if (item != null && p.casItem(item, null)) { unlink(p); return item; } } return null; }
/** * Removes the first element {@code e} such that * {@code o.equals(e)}, if such an element exists in this deque. * If the deque does not contain the element, it is unchanged. * * @param o element to be removed from this deque, if present * @return {@code true} if the deque contained the specified element * @throws NullPointerException if the specified element is null */ public boolean removeFirstOccurrence(Object o) { checkNotNull(o); for (Node<E> p = first(); p != null; p = succ(p)) { E item = p.item; if (item != null && o.equals(item) && p.casItem(item, null)) { unlink(p); return true; } } return false; }