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) { |
790 |
> |
if (remaining() > 1) { |
791 |
|
int mid = remaining >> 1; |
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 |
+ |
remaining(); // for the initialization side-effect |
805 |
|
for (; remaining > 0; cursor = inc(cursor, capacity), remaining--) |
806 |
|
action.accept(checkedElementAt(elements, cursor)); |
807 |
|
} |
808 |
|
|
809 |
|
public boolean tryAdvance(Consumer<? super E> action) { |
810 |
|
Objects.requireNonNull(action); |
811 |
< |
if (remaining <= 0) |
811 |
> |
if (remaining() == 0) |
812 |
|
return false; |
813 |
|
action.accept(checkedElementAt(elements, cursor)); |
814 |
|
cursor = inc(cursor, elements.length); |
817 |
|
} |
818 |
|
|
819 |
|
public long estimateSize() { |
820 |
< |
return remaining; |
820 |
> |
return remaining(); |
821 |
|
} |
822 |
|
|
823 |
|
public int characteristics() { |