Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7859 views
1
/*
2
* Written by Josh Bloch of Google Inc. and released to the public domain,
3
* as explained at http://creativecommons.org/publicdomain/zero/1.0/.
4
*/
5
6
package com.artifex.mupdfdemo;
7
8
import java.util.AbstractCollection;
9
import java.util.Arrays;
10
import java.util.Collection;
11
import java.util.ConcurrentModificationException;
12
import java.util.Iterator;
13
import java.util.LinkedList;
14
import java.util.List;
15
import java.util.NoSuchElementException;
16
import java.util.Queue;
17
import java.util.Stack;
18
19
// BEGIN android-note
20
// removed link to collections framework docs
21
// END android-note
22
23
/**
24
* Resizable-array implementation of the {@link Deque} interface. Array
25
* deques have no capacity restrictions; they grow as necessary to support
26
* usage. They are not thread-safe; in the absence of external
27
* synchronization, they do not support concurrent access by multiple threads.
28
* Null elements are prohibited. This class is likely to be faster than
29
* {@link Stack} when used as a stack, and faster than {@link LinkedList}
30
* when used as a queue.
31
*
32
* <p>Most <tt>ArrayDeque</tt> operations run in amortized constant time.
33
* Exceptions include {@link #remove(Object) remove}, {@link
34
* #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence
35
* removeLastOccurrence}, {@link #contains contains}, {@link #iterator
36
* iterator.remove()}, and the bulk operations, all of which run in linear
37
* time.
38
*
39
* <p>The iterators returned by this class's <tt>iterator</tt> method are
40
* <i>fail-fast</i>: If the deque is modified at any time after the iterator
41
* is created, in any way except through the iterator's own <tt>remove</tt>
42
* method, the iterator will generally throw a {@link
43
* ConcurrentModificationException}. Thus, in the face of concurrent
44
* modification, the iterator fails quickly and cleanly, rather than risking
45
* arbitrary, non-deterministic behavior at an undetermined time in the
46
* future.
47
*
48
* <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
49
* as it is, generally speaking, impossible to make any hard guarantees in the
50
* presence of unsynchronized concurrent modification. Fail-fast iterators
51
* throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
52
* Therefore, it would be wrong to write a program that depended on this
53
* exception for its correctness: <i>the fail-fast behavior of iterators
54
* should be used only to detect bugs.</i>
55
*
56
* <p>This class and its iterator implement all of the
57
* <em>optional</em> methods of the {@link Collection} and {@link
58
* Iterator} interfaces.
59
*
60
* @author Josh Bloch and Doug Lea
61
* @since 1.6
62
* @param <E> the type of elements held in this collection
63
*/
64
public class ArrayDeque<E> extends AbstractCollection<E>
65
implements Deque<E>, Cloneable, java.io.Serializable
66
{
67
/**
68
* The array in which the elements of the deque are stored.
69
* The capacity of the deque is the length of this array, which is
70
* always a power of two. The array is never allowed to become
71
* full, except transiently within an addX method where it is
72
* resized (see doubleCapacity) immediately upon becoming full,
73
* thus avoiding head and tail wrapping around to equal each
74
* other. We also guarantee that all array cells not holding
75
* deque elements are always null.
76
*/
77
private transient Object[] elements;
78
79
/**
80
* The index of the element at the head of the deque (which is the
81
* element that would be removed by remove() or pop()); or an
82
* arbitrary number equal to tail if the deque is empty.
83
*/
84
private transient int head;
85
86
/**
87
* The index at which the next element would be added to the tail
88
* of the deque (via addLast(E), add(E), or push(E)).
89
*/
90
private transient int tail;
91
92
/**
93
* The minimum capacity that we'll use for a newly created deque.
94
* Must be a power of 2.
95
*/
96
private static final int MIN_INITIAL_CAPACITY = 8;
97
98
// ****** Array allocation and resizing utilities ******
99
100
/**
101
* Allocate empty array to hold the given number of elements.
102
*
103
* @param numElements the number of elements to hold
104
*/
105
private void allocateElements(int numElements) {
106
int initialCapacity = MIN_INITIAL_CAPACITY;
107
// Find the best power of two to hold elements.
108
// Tests "<=" because arrays aren't kept full.
109
if (numElements >= initialCapacity) {
110
initialCapacity = numElements;
111
initialCapacity |= (initialCapacity >>> 1);
112
initialCapacity |= (initialCapacity >>> 2);
113
initialCapacity |= (initialCapacity >>> 4);
114
initialCapacity |= (initialCapacity >>> 8);
115
initialCapacity |= (initialCapacity >>> 16);
116
initialCapacity++;
117
118
if (initialCapacity < 0) // Too many elements, must back off
119
initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements
120
}
121
elements = new Object[initialCapacity];
122
}
123
124
/**
125
* Double the capacity of this deque. Call only when full, i.e.,
126
* when head and tail have wrapped around to become equal.
127
*/
128
private void doubleCapacity() {
129
// assert head == tail;
130
int p = head;
131
int n = elements.length;
132
int r = n - p; // number of elements to the right of p
133
int newCapacity = n << 1;
134
if (newCapacity < 0)
135
throw new IllegalStateException("Sorry, deque too big");
136
Object[] a = new Object[newCapacity];
137
System.arraycopy(elements, p, a, 0, r);
138
System.arraycopy(elements, 0, a, r, p);
139
elements = a;
140
head = 0;
141
tail = n;
142
}
143
144
/**
145
* Copies the elements from our element array into the specified array,
146
* in order (from first to last element in the deque). It is assumed
147
* that the array is large enough to hold all elements in the deque.
148
*
149
* @return its argument
150
*/
151
private <T> T[] copyElements(T[] a) {
152
if (head < tail) {
153
System.arraycopy(elements, head, a, 0, size());
154
} else if (head > tail) {
155
int headPortionLen = elements.length - head;
156
System.arraycopy(elements, head, a, 0, headPortionLen);
157
System.arraycopy(elements, 0, a, headPortionLen, tail);
158
}
159
return a;
160
}
161
162
/**
163
* Constructs an empty array deque with an initial capacity
164
* sufficient to hold 16 elements.
165
*/
166
public ArrayDeque() {
167
elements = new Object[16];
168
}
169
170
/**
171
* Constructs an empty array deque with an initial capacity
172
* sufficient to hold the specified number of elements.
173
*
174
* @param numElements lower bound on initial capacity of the deque
175
*/
176
public ArrayDeque(int numElements) {
177
allocateElements(numElements);
178
}
179
180
/**
181
* Constructs a deque containing the elements of the specified
182
* collection, in the order they are returned by the collection's
183
* iterator. (The first element returned by the collection's
184
* iterator becomes the first element, or <i>front</i> of the
185
* deque.)
186
*
187
* @param c the collection whose elements are to be placed into the deque
188
* @throws NullPointerException if the specified collection is null
189
*/
190
public ArrayDeque(Collection<? extends E> c) {
191
allocateElements(c.size());
192
addAll(c);
193
}
194
195
// The main insertion and extraction methods are addFirst,
196
// addLast, pollFirst, pollLast. The other methods are defined in
197
// terms of these.
198
199
/**
200
* Inserts the specified element at the front of this deque.
201
*
202
* @param e the element to add
203
* @throws NullPointerException if the specified element is null
204
*/
205
public void addFirst(E e) {
206
if (e == null)
207
throw new NullPointerException("e == null");
208
elements[head = (head - 1) & (elements.length - 1)] = e;
209
if (head == tail)
210
doubleCapacity();
211
}
212
213
/**
214
* Inserts the specified element at the end of this deque.
215
*
216
* <p>This method is equivalent to {@link #add}.
217
*
218
* @param e the element to add
219
* @throws NullPointerException if the specified element is null
220
*/
221
public void addLast(E e) {
222
if (e == null)
223
throw new NullPointerException("e == null");
224
elements[tail] = e;
225
if ( (tail = (tail + 1) & (elements.length - 1)) == head)
226
doubleCapacity();
227
}
228
229
/**
230
* Inserts the specified element at the front of this deque.
231
*
232
* @param e the element to add
233
* @return <tt>true</tt> (as specified by {@link Deque#offerFirst})
234
* @throws NullPointerException if the specified element is null
235
*/
236
public boolean offerFirst(E e) {
237
addFirst(e);
238
return true;
239
}
240
241
/**
242
* Inserts the specified element at the end of this deque.
243
*
244
* @param e the element to add
245
* @return <tt>true</tt> (as specified by {@link Deque#offerLast})
246
* @throws NullPointerException if the specified element is null
247
*/
248
public boolean offerLast(E e) {
249
addLast(e);
250
return true;
251
}
252
253
/**
254
* @throws NoSuchElementException {@inheritDoc}
255
*/
256
public E removeFirst() {
257
E x = pollFirst();
258
if (x == null)
259
throw new NoSuchElementException();
260
return x;
261
}
262
263
/**
264
* @throws NoSuchElementException {@inheritDoc}
265
*/
266
public E removeLast() {
267
E x = pollLast();
268
if (x == null)
269
throw new NoSuchElementException();
270
return x;
271
}
272
273
public E pollFirst() {
274
int h = head;
275
@SuppressWarnings("unchecked") E result = (E) elements[h];
276
// Element is null if deque empty
277
if (result == null)
278
return null;
279
elements[h] = null; // Must null out slot
280
head = (h + 1) & (elements.length - 1);
281
return result;
282
}
283
284
public E pollLast() {
285
int t = (tail - 1) & (elements.length - 1);
286
@SuppressWarnings("unchecked") E result = (E) elements[t];
287
if (result == null)
288
return null;
289
elements[t] = null;
290
tail = t;
291
return result;
292
}
293
294
/**
295
* @throws NoSuchElementException {@inheritDoc}
296
*/
297
public E getFirst() {
298
@SuppressWarnings("unchecked") E result = (E) elements[head];
299
if (result == null)
300
throw new NoSuchElementException();
301
return result;
302
}
303
304
/**
305
* @throws NoSuchElementException {@inheritDoc}
306
*/
307
public E getLast() {
308
@SuppressWarnings("unchecked")
309
E result = (E) elements[(tail - 1) & (elements.length - 1)];
310
if (result == null)
311
throw new NoSuchElementException();
312
return result;
313
}
314
315
public E peekFirst() {
316
@SuppressWarnings("unchecked") E result = (E) elements[head];
317
// elements[head] is null if deque empty
318
return result;
319
}
320
321
public E peekLast() {
322
@SuppressWarnings("unchecked")
323
E result = (E) elements[(tail - 1) & (elements.length - 1)];
324
return result;
325
}
326
327
/**
328
* Removes the first occurrence of the specified element in this
329
* deque (when traversing the deque from head to tail).
330
* If the deque does not contain the element, it is unchanged.
331
* More formally, removes the first element <tt>e</tt> such that
332
* <tt>o.equals(e)</tt> (if such an element exists).
333
* Returns <tt>true</tt> if this deque contained the specified element
334
* (or equivalently, if this deque changed as a result of the call).
335
*
336
* @param o element to be removed from this deque, if present
337
* @return <tt>true</tt> if the deque contained the specified element
338
*/
339
public boolean removeFirstOccurrence(Object o) {
340
if (o == null)
341
return false;
342
int mask = elements.length - 1;
343
int i = head;
344
Object x;
345
while ( (x = elements[i]) != null) {
346
if (o.equals(x)) {
347
delete(i);
348
return true;
349
}
350
i = (i + 1) & mask;
351
}
352
return false;
353
}
354
355
/**
356
* Removes the last occurrence of the specified element in this
357
* deque (when traversing the deque from head to tail).
358
* If the deque does not contain the element, it is unchanged.
359
* More formally, removes the last element <tt>e</tt> such that
360
* <tt>o.equals(e)</tt> (if such an element exists).
361
* Returns <tt>true</tt> if this deque contained the specified element
362
* (or equivalently, if this deque changed as a result of the call).
363
*
364
* @param o element to be removed from this deque, if present
365
* @return <tt>true</tt> if the deque contained the specified element
366
*/
367
public boolean removeLastOccurrence(Object o) {
368
if (o == null)
369
return false;
370
int mask = elements.length - 1;
371
int i = (tail - 1) & mask;
372
Object x;
373
while ( (x = elements[i]) != null) {
374
if (o.equals(x)) {
375
delete(i);
376
return true;
377
}
378
i = (i - 1) & mask;
379
}
380
return false;
381
}
382
383
// *** Queue methods ***
384
385
/**
386
* Inserts the specified element at the end of this deque.
387
*
388
* <p>This method is equivalent to {@link #addLast}.
389
*
390
* @param e the element to add
391
* @return <tt>true</tt> (as specified by {@link Collection#add})
392
* @throws NullPointerException if the specified element is null
393
*/
394
public boolean add(E e) {
395
addLast(e);
396
return true;
397
}
398
399
/**
400
* Inserts the specified element at the end of this deque.
401
*
402
* <p>This method is equivalent to {@link #offerLast}.
403
*
404
* @param e the element to add
405
* @return <tt>true</tt> (as specified by {@link Queue#offer})
406
* @throws NullPointerException if the specified element is null
407
*/
408
public boolean offer(E e) {
409
return offerLast(e);
410
}
411
412
/**
413
* Retrieves and removes the head of the queue represented by this deque.
414
*
415
* This method differs from {@link #poll poll} only in that it throws an
416
* exception if this deque is empty.
417
*
418
* <p>This method is equivalent to {@link #removeFirst}.
419
*
420
* @return the head of the queue represented by this deque
421
* @throws NoSuchElementException {@inheritDoc}
422
*/
423
public E remove() {
424
return removeFirst();
425
}
426
427
/**
428
* Retrieves and removes the head of the queue represented by this deque
429
* (in other words, the first element of this deque), or returns
430
* <tt>null</tt> if this deque is empty.
431
*
432
* <p>This method is equivalent to {@link #pollFirst}.
433
*
434
* @return the head of the queue represented by this deque, or
435
* <tt>null</tt> if this deque is empty
436
*/
437
public E poll() {
438
return pollFirst();
439
}
440
441
/**
442
* Retrieves, but does not remove, the head of the queue represented by
443
* this deque. This method differs from {@link #peek peek} only in
444
* that it throws an exception if this deque is empty.
445
*
446
* <p>This method is equivalent to {@link #getFirst}.
447
*
448
* @return the head of the queue represented by this deque
449
* @throws NoSuchElementException {@inheritDoc}
450
*/
451
public E element() {
452
return getFirst();
453
}
454
455
/**
456
* Retrieves, but does not remove, the head of the queue represented by
457
* this deque, or returns <tt>null</tt> if this deque is empty.
458
*
459
* <p>This method is equivalent to {@link #peekFirst}.
460
*
461
* @return the head of the queue represented by this deque, or
462
* <tt>null</tt> if this deque is empty
463
*/
464
public E peek() {
465
return peekFirst();
466
}
467
468
// *** Stack methods ***
469
470
/**
471
* Pushes an element onto the stack represented by this deque. In other
472
* words, inserts the element at the front of this deque.
473
*
474
* <p>This method is equivalent to {@link #addFirst}.
475
*
476
* @param e the element to push
477
* @throws NullPointerException if the specified element is null
478
*/
479
public void push(E e) {
480
addFirst(e);
481
}
482
483
/**
484
* Pops an element from the stack represented by this deque. In other
485
* words, removes and returns the first element of this deque.
486
*
487
* <p>This method is equivalent to {@link #removeFirst()}.
488
*
489
* @return the element at the front of this deque (which is the top
490
* of the stack represented by this deque)
491
* @throws NoSuchElementException {@inheritDoc}
492
*/
493
public E pop() {
494
return removeFirst();
495
}
496
497
private void checkInvariants() {
498
// assert elements[tail] == null;
499
// assert head == tail ? elements[head] == null :
500
// (elements[head] != null &&
501
// elements[(tail - 1) & (elements.length - 1)] != null);
502
// assert elements[(head - 1) & (elements.length - 1)] == null;
503
}
504
505
/**
506
* Removes the element at the specified position in the elements array,
507
* adjusting head and tail as necessary. This can result in motion of
508
* elements backwards or forwards in the array.
509
*
510
* <p>This method is called delete rather than remove to emphasize
511
* that its semantics differ from those of {@link List#remove(int)}.
512
*
513
* @return true if elements moved backwards
514
*/
515
private boolean delete(int i) {
516
//checkInvariants();
517
final Object[] elements = this.elements;
518
final int mask = elements.length - 1;
519
final int h = head;
520
final int t = tail;
521
final int front = (i - h) & mask;
522
final int back = (t - i) & mask;
523
524
// Invariant: head <= i < tail mod circularity
525
if (front >= ((t - h) & mask))
526
throw new ConcurrentModificationException();
527
528
// Optimize for least element motion
529
if (front < back) {
530
if (h <= i) {
531
System.arraycopy(elements, h, elements, h + 1, front);
532
} else { // Wrap around
533
System.arraycopy(elements, 0, elements, 1, i);
534
elements[0] = elements[mask];
535
System.arraycopy(elements, h, elements, h + 1, mask - h);
536
}
537
elements[h] = null;
538
head = (h + 1) & mask;
539
return false;
540
} else {
541
if (i < t) { // Copy the null tail as well
542
System.arraycopy(elements, i + 1, elements, i, back);
543
tail = t - 1;
544
} else { // Wrap around
545
System.arraycopy(elements, i + 1, elements, i, mask - i);
546
elements[mask] = elements[0];
547
System.arraycopy(elements, 1, elements, 0, t);
548
tail = (t - 1) & mask;
549
}
550
return true;
551
}
552
}
553
554
// *** Collection Methods ***
555
556
/**
557
* Returns the number of elements in this deque.
558
*
559
* @return the number of elements in this deque
560
*/
561
public int size() {
562
return (tail - head) & (elements.length - 1);
563
}
564
565
/**
566
* Returns <tt>true</tt> if this deque contains no elements.
567
*
568
* @return <tt>true</tt> if this deque contains no elements
569
*/
570
public boolean isEmpty() {
571
return head == tail;
572
}
573
574
/**
575
* Returns an iterator over the elements in this deque. The elements
576
* will be ordered from first (head) to last (tail). This is the same
577
* order that elements would be dequeued (via successive calls to
578
* {@link #remove} or popped (via successive calls to {@link #pop}).
579
*
580
* @return an iterator over the elements in this deque
581
*/
582
public Iterator<E> iterator() {
583
return new DeqIterator();
584
}
585
586
public Iterator<E> descendingIterator() {
587
return new DescendingIterator();
588
}
589
590
private class DeqIterator implements Iterator<E> {
591
/**
592
* Index of element to be returned by subsequent call to next.
593
*/
594
private int cursor = head;
595
596
/**
597
* Tail recorded at construction (also in remove), to stop
598
* iterator and also to check for comodification.
599
*/
600
private int fence = tail;
601
602
/**
603
* Index of element returned by most recent call to next.
604
* Reset to -1 if element is deleted by a call to remove.
605
*/
606
private int lastRet = -1;
607
608
public boolean hasNext() {
609
return cursor != fence;
610
}
611
612
public E next() {
613
if (cursor == fence)
614
throw new NoSuchElementException();
615
@SuppressWarnings("unchecked") E result = (E) elements[cursor];
616
// This check doesn't catch all possible comodifications,
617
// but does catch the ones that corrupt traversal
618
if (tail != fence || result == null)
619
throw new ConcurrentModificationException();
620
lastRet = cursor;
621
cursor = (cursor + 1) & (elements.length - 1);
622
return result;
623
}
624
625
public void remove() {
626
if (lastRet < 0)
627
throw new IllegalStateException();
628
if (delete(lastRet)) { // if left-shifted, undo increment in next()
629
cursor = (cursor - 1) & (elements.length - 1);
630
fence = tail;
631
}
632
lastRet = -1;
633
}
634
}
635
636
private class DescendingIterator implements Iterator<E> {
637
/*
638
* This class is nearly a mirror-image of DeqIterator, using
639
* tail instead of head for initial cursor, and head instead of
640
* tail for fence.
641
*/
642
private int cursor = tail;
643
private int fence = head;
644
private int lastRet = -1;
645
646
public boolean hasNext() {
647
return cursor != fence;
648
}
649
650
public E next() {
651
if (cursor == fence)
652
throw new NoSuchElementException();
653
cursor = (cursor - 1) & (elements.length - 1);
654
@SuppressWarnings("unchecked") E result = (E) elements[cursor];
655
if (head != fence || result == null)
656
throw new ConcurrentModificationException();
657
lastRet = cursor;
658
return result;
659
}
660
661
public void remove() {
662
if (lastRet < 0)
663
throw new IllegalStateException();
664
if (!delete(lastRet)) {
665
cursor = (cursor + 1) & (elements.length - 1);
666
fence = head;
667
}
668
lastRet = -1;
669
}
670
}
671
672
/**
673
* Returns <tt>true</tt> if this deque contains the specified element.
674
* More formally, returns <tt>true</tt> if and only if this deque contains
675
* at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
676
*
677
* @param o object to be checked for containment in this deque
678
* @return <tt>true</tt> if this deque contains the specified element
679
*/
680
public boolean contains(Object o) {
681
if (o == null)
682
return false;
683
int mask = elements.length - 1;
684
int i = head;
685
Object x;
686
while ( (x = elements[i]) != null) {
687
if (o.equals(x))
688
return true;
689
i = (i + 1) & mask;
690
}
691
return false;
692
}
693
694
/**
695
* Removes a single instance of the specified element from this deque.
696
* If the deque does not contain the element, it is unchanged.
697
* More formally, removes the first element <tt>e</tt> such that
698
* <tt>o.equals(e)</tt> (if such an element exists).
699
* Returns <tt>true</tt> if this deque contained the specified element
700
* (or equivalently, if this deque changed as a result of the call).
701
*
702
* <p>This method is equivalent to {@link #removeFirstOccurrence}.
703
*
704
* @param o element to be removed from this deque, if present
705
* @return <tt>true</tt> if this deque contained the specified element
706
*/
707
public boolean remove(Object o) {
708
return removeFirstOccurrence(o);
709
}
710
711
/**
712
* Removes all of the elements from this deque.
713
* The deque will be empty after this call returns.
714
*/
715
public void clear() {
716
int h = head;
717
int t = tail;
718
if (h != t) { // clear all cells
719
head = tail = 0;
720
int i = h;
721
int mask = elements.length - 1;
722
do {
723
elements[i] = null;
724
i = (i + 1) & mask;
725
} while (i != t);
726
}
727
}
728
729
/**
730
* Returns an array containing all of the elements in this deque
731
* in proper sequence (from first to last element).
732
*
733
* <p>The returned array will be "safe" in that no references to it are
734
* maintained by this deque. (In other words, this method must allocate
735
* a new array). The caller is thus free to modify the returned array.
736
*
737
* <p>This method acts as bridge between array-based and collection-based
738
* APIs.
739
*
740
* @return an array containing all of the elements in this deque
741
*/
742
public Object[] toArray() {
743
return copyElements(new Object[size()]);
744
}
745
746
/**
747
* Returns an array containing all of the elements in this deque in
748
* proper sequence (from first to last element); the runtime type of the
749
* returned array is that of the specified array. If the deque fits in
750
* the specified array, it is returned therein. Otherwise, a new array
751
* is allocated with the runtime type of the specified array and the
752
* size of this deque.
753
*
754
* <p>If this deque fits in the specified array with room to spare
755
* (i.e., the array has more elements than this deque), the element in
756
* the array immediately following the end of the deque is set to
757
* <tt>null</tt>.
758
*
759
* <p>Like the {@link #toArray()} method, this method acts as bridge between
760
* array-based and collection-based APIs. Further, this method allows
761
* precise control over the runtime type of the output array, and may,
762
* under certain circumstances, be used to save allocation costs.
763
*
764
* <p>Suppose <tt>x</tt> is a deque known to contain only strings.
765
* The following code can be used to dump the deque into a newly
766
* allocated array of <tt>String</tt>:
767
*
768
* <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
769
*
770
* Note that <tt>toArray(new Object[0])</tt> is identical in function to
771
* <tt>toArray()</tt>.
772
*
773
* @param a the array into which the elements of the deque are to
774
* be stored, if it is big enough; otherwise, a new array of the
775
* same runtime type is allocated for this purpose
776
* @return an array containing all of the elements in this deque
777
* @throws ArrayStoreException if the runtime type of the specified array
778
* is not a supertype of the runtime type of every element in
779
* this deque
780
* @throws NullPointerException if the specified array is null
781
*/
782
@SuppressWarnings("unchecked")
783
public <T> T[] toArray(T[] a) {
784
int size = size();
785
if (a.length < size)
786
a = (T[])java.lang.reflect.Array.newInstance(
787
a.getClass().getComponentType(), size);
788
copyElements(a);
789
if (a.length > size)
790
a[size] = null;
791
return a;
792
}
793
794
// *** Object methods ***
795
796
/**
797
* Returns a copy of this deque.
798
*
799
* @return a copy of this deque
800
*/
801
public ArrayDeque<E> clone() {
802
try {
803
@SuppressWarnings("unchecked")
804
ArrayDeque<E> result = (ArrayDeque<E>) super.clone();
805
result.elements = Arrays.copyOf(elements, elements.length);
806
return result;
807
808
} catch (CloneNotSupportedException e) {
809
throw new AssertionError();
810
}
811
}
812
813
/**
814
* Appease the serialization gods.
815
*/
816
private static final long serialVersionUID = 2340985798034038923L;
817
818
/**
819
* Serialize this deque.
820
*
821
* @serialData The current size (<tt>int</tt>) of the deque,
822
* followed by all of its elements (each an object reference) in
823
* first-to-last order.
824
*/
825
private void writeObject(java.io.ObjectOutputStream s)
826
throws java.io.IOException {
827
s.defaultWriteObject();
828
829
// Write out size
830
s.writeInt(size());
831
832
// Write out elements in order.
833
int mask = elements.length - 1;
834
for (int i = head; i != tail; i = (i + 1) & mask)
835
s.writeObject(elements[i]);
836
}
837
838
/**
839
* Deserialize this deque.
840
*/
841
private void readObject(java.io.ObjectInputStream s)
842
throws java.io.IOException, ClassNotFoundException {
843
s.defaultReadObject();
844
845
// Read in size and allocate array
846
int size = s.readInt();
847
allocateElements(size);
848
head = 0;
849
tail = size;
850
851
// Read in all elements in the proper order.
852
for (int i = 0; i < size; i++)
853
elements[i] = s.readObject();
854
}
855
}
856
857