772 |
|
return current != null; |
773 |
|
} |
774 |
|
|
775 |
– |
/** |
776 |
– |
* Returns the next live successor of p, or null if no such. |
777 |
– |
* |
778 |
– |
* Unlike other traversal methods, iterators need to handle both: |
779 |
– |
* - dequeued nodes (p.next == p) |
780 |
– |
* - (possibly multiple) interior removed nodes (p.item == null) |
781 |
– |
*/ |
782 |
– |
private Node<E> nextNode(Node<E> p) { |
783 |
– |
for (;;) { |
784 |
– |
Node<E> s = p.next; |
785 |
– |
if (s == p) |
786 |
– |
return head.next; |
787 |
– |
if (s == null || s.item != null) |
788 |
– |
return s; |
789 |
– |
p = s; |
790 |
– |
} |
791 |
– |
} |
792 |
– |
|
775 |
|
public E next() { |
776 |
|
fullyLock(); |
777 |
|
try { |
778 |
|
if (current == null) |
779 |
|
throw new NoSuchElementException(); |
798 |
– |
E x = currentElement; |
780 |
|
lastRet = current; |
781 |
< |
current = nextNode(current); |
782 |
< |
currentElement = (current == null) ? null : current.item; |
783 |
< |
return x; |
781 |
> |
E item = null; |
782 |
> |
// Unlike other traversal methods, iterators must handle both: |
783 |
> |
// - dequeued nodes (p.next == p) |
784 |
> |
// - (possibly multiple) interior removed nodes (p.item == null) |
785 |
> |
for (Node<E> p = current, q;; p = q) { |
786 |
> |
if ((q = p.next) == p) |
787 |
> |
q = head.next; |
788 |
> |
if (q == null || (item = q.item) != null) { |
789 |
> |
current = q; |
790 |
> |
E x = currentElement; |
791 |
> |
currentElement = item; |
792 |
> |
return x; |
793 |
> |
} |
794 |
> |
} |
795 |
|
} finally { |
796 |
|
fullyUnlock(); |
797 |
|
} |