689 |
|
|
690 |
|
DeqIterator() { cursor = head; } |
691 |
|
|
692 |
< |
void doAdvance() { |
693 |
< |
cursor = inc(cursor, elements.length); |
692 |
> |
int advance(int i, int modulus) { |
693 |
> |
return inc(i, modulus); |
694 |
|
} |
695 |
|
|
696 |
|
void doRemove() { |
708 |
|
throw new NoSuchElementException(); |
709 |
|
E e = checkedElementAt(elements, cursor); |
710 |
|
lastRet = cursor; |
711 |
< |
doAdvance(); |
711 |
> |
cursor = advance(cursor, elements.length); |
712 |
|
remaining--; |
713 |
|
return e; |
714 |
|
} |
724 |
|
Objects.requireNonNull(action); |
725 |
|
final Object[] elements = ArrayDeque.this.elements; |
726 |
|
final int capacity = elements.length; |
727 |
< |
for (; remaining > 0; remaining--) { |
728 |
< |
action.accept(checkedElementAt(elements, cursor)); |
729 |
< |
doAdvance(); |
730 |
< |
} |
727 |
> |
int k = remaining; |
728 |
> |
remaining = 0; |
729 |
> |
for (int i = cursor; --k >= 0; i = advance(i, capacity)) |
730 |
> |
action.accept(checkedElementAt(elements, i)); |
731 |
|
} |
732 |
|
} |
733 |
|
|
734 |
|
private class DescendingIterator extends DeqIterator { |
735 |
|
DescendingIterator() { cursor = tail(); } |
736 |
|
|
737 |
< |
@Override void doAdvance() { |
738 |
< |
cursor = dec(cursor, elements.length); |
737 |
> |
@Override int advance(int i, int modulus) { |
738 |
> |
return dec(i, modulus); |
739 |
|
} |
740 |
|
|
741 |
|
@Override void doRemove() { |
759 |
|
* @since 1.8 |
760 |
|
*/ |
761 |
|
public Spliterator<E> spliterator() { |
762 |
< |
return new ArrayDequeSpliterator(head, size); |
762 |
> |
return new ArrayDequeSpliterator(); |
763 |
|
} |
764 |
|
|
765 |
|
final class ArrayDequeSpliterator implements Spliterator<E> { |
766 |
|
private int cursor; |
767 |
< |
private int remaining; |
767 |
> |
private int remaining; // -1 until late-binding first use |
768 |
|
|
769 |
< |
/** Creates new spliterator covering the given array slice. */ |
769 |
> |
/** Constructs late-binding spliterator over all elements. */ |
770 |
> |
ArrayDequeSpliterator() { |
771 |
> |
this.remaining = -1; |
772 |
> |
} |
773 |
> |
|
774 |
> |
/** Constructs spliterator over the given slice. */ |
775 |
|
ArrayDequeSpliterator(int cursor, int count) { |
776 |
|
this.cursor = cursor; |
777 |
|
this.remaining = count; |
778 |
|
} |
779 |
|
|
780 |
+ |
/** Ensures late-binding initialization; then returns remaining. */ |
781 |
+ |
private int remaining() { |
782 |
+ |
if (remaining < 0) { |
783 |
+ |
cursor = head; |
784 |
+ |
remaining = size; |
785 |
+ |
} |
786 |
+ |
return remaining; |
787 |
+ |
} |
788 |
+ |
|
789 |
|
public ArrayDequeSpliterator trySplit() { |
790 |
< |
if (remaining > 1) { |
791 |
< |
int mid = remaining >> 1; |
790 |
> |
final int mid; |
791 |
> |
if ((mid = remaining() >> 1) > 0) { |
792 |
|
int oldCursor = cursor; |
793 |
< |
cursor += mid; |
780 |
< |
if (cursor >= elements.length) cursor -= elements.length; |
793 |
> |
cursor = add(cursor, mid, elements.length); |
794 |
|
remaining -= mid; |
795 |
|
return new ArrayDequeSpliterator(oldCursor, mid); |
796 |
|
} |
801 |
|
Objects.requireNonNull(action); |
802 |
|
final Object[] elements = ArrayDeque.this.elements; |
803 |
|
final int capacity = elements.length; |
804 |
< |
for (; remaining > 0; cursor = inc(cursor, capacity), remaining--) |
805 |
< |
action.accept(checkedElementAt(elements, cursor)); |
804 |
> |
int k = remaining(); |
805 |
> |
remaining = 0; |
806 |
> |
for (int i = cursor; --k >= 0; i = inc(i, capacity)) |
807 |
> |
action.accept(checkedElementAt(elements, i)); |
808 |
|
} |
809 |
|
|
810 |
|
public boolean tryAdvance(Consumer<? super E> action) { |
811 |
|
Objects.requireNonNull(action); |
812 |
< |
if (remaining <= 0) |
812 |
> |
if (remaining() == 0) |
813 |
|
return false; |
814 |
|
action.accept(checkedElementAt(elements, cursor)); |
815 |
|
cursor = inc(cursor, elements.length); |
818 |
|
} |
819 |
|
|
820 |
|
public long estimateSize() { |
821 |
< |
return remaining; |
821 |
> |
return remaining(); |
822 |
|
} |
823 |
|
|
824 |
|
public int characteristics() { |