|
1 /* |
|
2 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Sun designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Sun in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
22 * CA 95054 USA or visit www.sun.com if you need additional information or |
|
23 * have any questions. |
|
24 */ |
|
25 |
|
26 package java.util; |
|
27 |
|
28 /** |
|
29 * Linked list implementation of the <tt>List</tt> interface. Implements all |
|
30 * optional list operations, and permits all elements (including |
|
31 * <tt>null</tt>). In addition to implementing the <tt>List</tt> interface, |
|
32 * the <tt>LinkedList</tt> class provides uniformly named methods to |
|
33 * <tt>get</tt>, <tt>remove</tt> and <tt>insert</tt> an element at the |
|
34 * beginning and end of the list. These operations allow linked lists to be |
|
35 * used as a stack, {@linkplain Queue queue}, or {@linkplain Deque |
|
36 * double-ended queue}. <p> |
|
37 * |
|
38 * The class implements the <tt>Deque</tt> interface, providing |
|
39 * first-in-first-out queue operations for <tt>add</tt>, |
|
40 * <tt>poll</tt>, along with other stack and deque operations.<p> |
|
41 * |
|
42 * All of the operations perform as could be expected for a doubly-linked |
|
43 * list. Operations that index into the list will traverse the list from |
|
44 * the beginning or the end, whichever is closer to the specified index.<p> |
|
45 * |
|
46 * <p><strong>Note that this implementation is not synchronized.</strong> |
|
47 * If multiple threads access a linked list concurrently, and at least |
|
48 * one of the threads modifies the list structurally, it <i>must</i> be |
|
49 * synchronized externally. (A structural modification is any operation |
|
50 * that adds or deletes one or more elements; merely setting the value of |
|
51 * an element is not a structural modification.) This is typically |
|
52 * accomplished by synchronizing on some object that naturally |
|
53 * encapsulates the list. |
|
54 * |
|
55 * If no such object exists, the list should be "wrapped" using the |
|
56 * {@link Collections#synchronizedList Collections.synchronizedList} |
|
57 * method. This is best done at creation time, to prevent accidental |
|
58 * unsynchronized access to the list:<pre> |
|
59 * List list = Collections.synchronizedList(new LinkedList(...));</pre> |
|
60 * |
|
61 * <p>The iterators returned by this class's <tt>iterator</tt> and |
|
62 * <tt>listIterator</tt> methods are <i>fail-fast</i>: if the list is |
|
63 * structurally modified at any time after the iterator is created, in |
|
64 * any way except through the Iterator's own <tt>remove</tt> or |
|
65 * <tt>add</tt> methods, the iterator will throw a {@link |
|
66 * ConcurrentModificationException}. Thus, in the face of concurrent |
|
67 * modification, the iterator fails quickly and cleanly, rather than |
|
68 * risking arbitrary, non-deterministic behavior at an undetermined |
|
69 * time in the future. |
|
70 * |
|
71 * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed |
|
72 * as it is, generally speaking, impossible to make any hard guarantees in the |
|
73 * presence of unsynchronized concurrent modification. Fail-fast iterators |
|
74 * throw <tt>ConcurrentModificationException</tt> on a best-effort basis. |
|
75 * Therefore, it would be wrong to write a program that depended on this |
|
76 * exception for its correctness: <i>the fail-fast behavior of iterators |
|
77 * should be used only to detect bugs.</i> |
|
78 * |
|
79 * <p>This class is a member of the |
|
80 * <a href="{@docRoot}/../technotes/guides/collections/index.html"> |
|
81 * Java Collections Framework</a>. |
|
82 * |
|
83 * @author Josh Bloch |
|
84 * @see List |
|
85 * @see ArrayList |
|
86 * @see Vector |
|
87 * @since 1.2 |
|
88 * @param <E> the type of elements held in this collection |
|
89 */ |
|
90 |
|
91 public class LinkedList<E> |
|
92 extends AbstractSequentialList<E> |
|
93 implements List<E>, Deque<E>, Cloneable, java.io.Serializable |
|
94 { |
|
95 private transient Entry<E> header = new Entry<E>(null, null, null); |
|
96 private transient int size = 0; |
|
97 |
|
98 /** |
|
99 * Constructs an empty list. |
|
100 */ |
|
101 public LinkedList() { |
|
102 header.next = header.previous = header; |
|
103 } |
|
104 |
|
105 /** |
|
106 * Constructs a list containing the elements of the specified |
|
107 * collection, in the order they are returned by the collection's |
|
108 * iterator. |
|
109 * |
|
110 * @param c the collection whose elements are to be placed into this list |
|
111 * @throws NullPointerException if the specified collection is null |
|
112 */ |
|
113 public LinkedList(Collection<? extends E> c) { |
|
114 this(); |
|
115 addAll(c); |
|
116 } |
|
117 |
|
118 /** |
|
119 * Returns the first element in this list. |
|
120 * |
|
121 * @return the first element in this list |
|
122 * @throws NoSuchElementException if this list is empty |
|
123 */ |
|
124 public E getFirst() { |
|
125 if (size==0) |
|
126 throw new NoSuchElementException(); |
|
127 |
|
128 return header.next.element; |
|
129 } |
|
130 |
|
131 /** |
|
132 * Returns the last element in this list. |
|
133 * |
|
134 * @return the last element in this list |
|
135 * @throws NoSuchElementException if this list is empty |
|
136 */ |
|
137 public E getLast() { |
|
138 if (size==0) |
|
139 throw new NoSuchElementException(); |
|
140 |
|
141 return header.previous.element; |
|
142 } |
|
143 |
|
144 /** |
|
145 * Removes and returns the first element from this list. |
|
146 * |
|
147 * @return the first element from this list |
|
148 * @throws NoSuchElementException if this list is empty |
|
149 */ |
|
150 public E removeFirst() { |
|
151 return remove(header.next); |
|
152 } |
|
153 |
|
154 /** |
|
155 * Removes and returns the last element from this list. |
|
156 * |
|
157 * @return the last element from this list |
|
158 * @throws NoSuchElementException if this list is empty |
|
159 */ |
|
160 public E removeLast() { |
|
161 return remove(header.previous); |
|
162 } |
|
163 |
|
164 /** |
|
165 * Inserts the specified element at the beginning of this list. |
|
166 * |
|
167 * @param e the element to add |
|
168 */ |
|
169 public void addFirst(E e) { |
|
170 addBefore(e, header.next); |
|
171 } |
|
172 |
|
173 /** |
|
174 * Appends the specified element to the end of this list. |
|
175 * |
|
176 * <p>This method is equivalent to {@link #add}. |
|
177 * |
|
178 * @param e the element to add |
|
179 */ |
|
180 public void addLast(E e) { |
|
181 addBefore(e, header); |
|
182 } |
|
183 |
|
184 /** |
|
185 * Returns <tt>true</tt> if this list contains the specified element. |
|
186 * More formally, returns <tt>true</tt> if and only if this list contains |
|
187 * at least one element <tt>e</tt> such that |
|
188 * <tt>(o==null ? e==null : o.equals(e))</tt>. |
|
189 * |
|
190 * @param o element whose presence in this list is to be tested |
|
191 * @return <tt>true</tt> if this list contains the specified element |
|
192 */ |
|
193 public boolean contains(Object o) { |
|
194 return indexOf(o) != -1; |
|
195 } |
|
196 |
|
197 /** |
|
198 * Returns the number of elements in this list. |
|
199 * |
|
200 * @return the number of elements in this list |
|
201 */ |
|
202 public int size() { |
|
203 return size; |
|
204 } |
|
205 |
|
206 /** |
|
207 * Appends the specified element to the end of this list. |
|
208 * |
|
209 * <p>This method is equivalent to {@link #addLast}. |
|
210 * |
|
211 * @param e element to be appended to this list |
|
212 * @return <tt>true</tt> (as specified by {@link Collection#add}) |
|
213 */ |
|
214 public boolean add(E e) { |
|
215 addBefore(e, header); |
|
216 return true; |
|
217 } |
|
218 |
|
219 /** |
|
220 * Removes the first occurrence of the specified element from this list, |
|
221 * if it is present. If this list does not contain the element, it is |
|
222 * unchanged. More formally, removes the element with the lowest index |
|
223 * <tt>i</tt> such that |
|
224 * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt> |
|
225 * (if such an element exists). Returns <tt>true</tt> if this list |
|
226 * contained the specified element (or equivalently, if this list |
|
227 * changed as a result of the call). |
|
228 * |
|
229 * @param o element to be removed from this list, if present |
|
230 * @return <tt>true</tt> if this list contained the specified element |
|
231 */ |
|
232 public boolean remove(Object o) { |
|
233 if (o==null) { |
|
234 for (Entry<E> e = header.next; e != header; e = e.next) { |
|
235 if (e.element==null) { |
|
236 remove(e); |
|
237 return true; |
|
238 } |
|
239 } |
|
240 } else { |
|
241 for (Entry<E> e = header.next; e != header; e = e.next) { |
|
242 if (o.equals(e.element)) { |
|
243 remove(e); |
|
244 return true; |
|
245 } |
|
246 } |
|
247 } |
|
248 return false; |
|
249 } |
|
250 |
|
251 /** |
|
252 * Appends all of the elements in the specified collection to the end of |
|
253 * this list, in the order that they are returned by the specified |
|
254 * collection's iterator. The behavior of this operation is undefined if |
|
255 * the specified collection is modified while the operation is in |
|
256 * progress. (Note that this will occur if the specified collection is |
|
257 * this list, and it's nonempty.) |
|
258 * |
|
259 * @param c collection containing elements to be added to this list |
|
260 * @return <tt>true</tt> if this list changed as a result of the call |
|
261 * @throws NullPointerException if the specified collection is null |
|
262 */ |
|
263 public boolean addAll(Collection<? extends E> c) { |
|
264 return addAll(size, c); |
|
265 } |
|
266 |
|
267 /** |
|
268 * Inserts all of the elements in the specified collection into this |
|
269 * list, starting at the specified position. Shifts the element |
|
270 * currently at that position (if any) and any subsequent elements to |
|
271 * the right (increases their indices). The new elements will appear |
|
272 * in the list in the order that they are returned by the |
|
273 * specified collection's iterator. |
|
274 * |
|
275 * @param index index at which to insert the first element |
|
276 * from the specified collection |
|
277 * @param c collection containing elements to be added to this list |
|
278 * @return <tt>true</tt> if this list changed as a result of the call |
|
279 * @throws IndexOutOfBoundsException {@inheritDoc} |
|
280 * @throws NullPointerException if the specified collection is null |
|
281 */ |
|
282 public boolean addAll(int index, Collection<? extends E> c) { |
|
283 if (index < 0 || index > size) |
|
284 throw new IndexOutOfBoundsException("Index: "+index+ |
|
285 ", Size: "+size); |
|
286 Object[] a = c.toArray(); |
|
287 int numNew = a.length; |
|
288 if (numNew==0) |
|
289 return false; |
|
290 modCount++; |
|
291 |
|
292 Entry<E> successor = (index==size ? header : entry(index)); |
|
293 Entry<E> predecessor = successor.previous; |
|
294 for (int i=0; i<numNew; i++) { |
|
295 Entry<E> e = new Entry<E>((E)a[i], successor, predecessor); |
|
296 predecessor.next = e; |
|
297 predecessor = e; |
|
298 } |
|
299 successor.previous = predecessor; |
|
300 |
|
301 size += numNew; |
|
302 return true; |
|
303 } |
|
304 |
|
305 /** |
|
306 * Removes all of the elements from this list. |
|
307 */ |
|
308 public void clear() { |
|
309 Entry<E> e = header.next; |
|
310 while (e != header) { |
|
311 Entry<E> next = e.next; |
|
312 e.next = e.previous = null; |
|
313 e.element = null; |
|
314 e = next; |
|
315 } |
|
316 header.next = header.previous = header; |
|
317 size = 0; |
|
318 modCount++; |
|
319 } |
|
320 |
|
321 |
|
322 // Positional Access Operations |
|
323 |
|
324 /** |
|
325 * Returns the element at the specified position in this list. |
|
326 * |
|
327 * @param index index of the element to return |
|
328 * @return the element at the specified position in this list |
|
329 * @throws IndexOutOfBoundsException {@inheritDoc} |
|
330 */ |
|
331 public E get(int index) { |
|
332 return entry(index).element; |
|
333 } |
|
334 |
|
335 /** |
|
336 * Replaces the element at the specified position in this list with the |
|
337 * specified element. |
|
338 * |
|
339 * @param index index of the element to replace |
|
340 * @param element element to be stored at the specified position |
|
341 * @return the element previously at the specified position |
|
342 * @throws IndexOutOfBoundsException {@inheritDoc} |
|
343 */ |
|
344 public E set(int index, E element) { |
|
345 Entry<E> e = entry(index); |
|
346 E oldVal = e.element; |
|
347 e.element = element; |
|
348 return oldVal; |
|
349 } |
|
350 |
|
351 /** |
|
352 * Inserts the specified element at the specified position in this list. |
|
353 * Shifts the element currently at that position (if any) and any |
|
354 * subsequent elements to the right (adds one to their indices). |
|
355 * |
|
356 * @param index index at which the specified element is to be inserted |
|
357 * @param element element to be inserted |
|
358 * @throws IndexOutOfBoundsException {@inheritDoc} |
|
359 */ |
|
360 public void add(int index, E element) { |
|
361 addBefore(element, (index==size ? header : entry(index))); |
|
362 } |
|
363 |
|
364 /** |
|
365 * Removes the element at the specified position in this list. Shifts any |
|
366 * subsequent elements to the left (subtracts one from their indices). |
|
367 * Returns the element that was removed from the list. |
|
368 * |
|
369 * @param index the index of the element to be removed |
|
370 * @return the element previously at the specified position |
|
371 * @throws IndexOutOfBoundsException {@inheritDoc} |
|
372 */ |
|
373 public E remove(int index) { |
|
374 return remove(entry(index)); |
|
375 } |
|
376 |
|
377 /** |
|
378 * Returns the indexed entry. |
|
379 */ |
|
380 private Entry<E> entry(int index) { |
|
381 if (index < 0 || index >= size) |
|
382 throw new IndexOutOfBoundsException("Index: "+index+ |
|
383 ", Size: "+size); |
|
384 Entry<E> e = header; |
|
385 if (index < (size >> 1)) { |
|
386 for (int i = 0; i <= index; i++) |
|
387 e = e.next; |
|
388 } else { |
|
389 for (int i = size; i > index; i--) |
|
390 e = e.previous; |
|
391 } |
|
392 return e; |
|
393 } |
|
394 |
|
395 |
|
396 // Search Operations |
|
397 |
|
398 /** |
|
399 * Returns the index of the first occurrence of the specified element |
|
400 * in this list, or -1 if this list does not contain the element. |
|
401 * More formally, returns the lowest index <tt>i</tt> such that |
|
402 * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, |
|
403 * or -1 if there is no such index. |
|
404 * |
|
405 * @param o element to search for |
|
406 * @return the index of the first occurrence of the specified element in |
|
407 * this list, or -1 if this list does not contain the element |
|
408 */ |
|
409 public int indexOf(Object o) { |
|
410 int index = 0; |
|
411 if (o==null) { |
|
412 for (Entry e = header.next; e != header; e = e.next) { |
|
413 if (e.element==null) |
|
414 return index; |
|
415 index++; |
|
416 } |
|
417 } else { |
|
418 for (Entry e = header.next; e != header; e = e.next) { |
|
419 if (o.equals(e.element)) |
|
420 return index; |
|
421 index++; |
|
422 } |
|
423 } |
|
424 return -1; |
|
425 } |
|
426 |
|
427 /** |
|
428 * Returns the index of the last occurrence of the specified element |
|
429 * in this list, or -1 if this list does not contain the element. |
|
430 * More formally, returns the highest index <tt>i</tt> such that |
|
431 * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, |
|
432 * or -1 if there is no such index. |
|
433 * |
|
434 * @param o element to search for |
|
435 * @return the index of the last occurrence of the specified element in |
|
436 * this list, or -1 if this list does not contain the element |
|
437 */ |
|
438 public int lastIndexOf(Object o) { |
|
439 int index = size; |
|
440 if (o==null) { |
|
441 for (Entry e = header.previous; e != header; e = e.previous) { |
|
442 index--; |
|
443 if (e.element==null) |
|
444 return index; |
|
445 } |
|
446 } else { |
|
447 for (Entry e = header.previous; e != header; e = e.previous) { |
|
448 index--; |
|
449 if (o.equals(e.element)) |
|
450 return index; |
|
451 } |
|
452 } |
|
453 return -1; |
|
454 } |
|
455 |
|
456 // Queue operations. |
|
457 |
|
458 /** |
|
459 * Retrieves, but does not remove, the head (first element) of this list. |
|
460 * @return the head of this list, or <tt>null</tt> if this list is empty |
|
461 * @since 1.5 |
|
462 */ |
|
463 public E peek() { |
|
464 if (size==0) |
|
465 return null; |
|
466 return getFirst(); |
|
467 } |
|
468 |
|
469 /** |
|
470 * Retrieves, but does not remove, the head (first element) of this list. |
|
471 * @return the head of this list |
|
472 * @throws NoSuchElementException if this list is empty |
|
473 * @since 1.5 |
|
474 */ |
|
475 public E element() { |
|
476 return getFirst(); |
|
477 } |
|
478 |
|
479 /** |
|
480 * Retrieves and removes the head (first element) of this list |
|
481 * @return the head of this list, or <tt>null</tt> if this list is empty |
|
482 * @since 1.5 |
|
483 */ |
|
484 public E poll() { |
|
485 if (size==0) |
|
486 return null; |
|
487 return removeFirst(); |
|
488 } |
|
489 |
|
490 /** |
|
491 * Retrieves and removes the head (first element) of this list. |
|
492 * |
|
493 * @return the head of this list |
|
494 * @throws NoSuchElementException if this list is empty |
|
495 * @since 1.5 |
|
496 */ |
|
497 public E remove() { |
|
498 return removeFirst(); |
|
499 } |
|
500 |
|
501 /** |
|
502 * Adds the specified element as the tail (last element) of this list. |
|
503 * |
|
504 * @param e the element to add |
|
505 * @return <tt>true</tt> (as specified by {@link Queue#offer}) |
|
506 * @since 1.5 |
|
507 */ |
|
508 public boolean offer(E e) { |
|
509 return add(e); |
|
510 } |
|
511 |
|
512 // Deque operations |
|
513 /** |
|
514 * Inserts the specified element at the front of this list. |
|
515 * |
|
516 * @param e the element to insert |
|
517 * @return <tt>true</tt> (as specified by {@link Deque#offerFirst}) |
|
518 * @since 1.6 |
|
519 */ |
|
520 public boolean offerFirst(E e) { |
|
521 addFirst(e); |
|
522 return true; |
|
523 } |
|
524 |
|
525 /** |
|
526 * Inserts the specified element at the end of this list. |
|
527 * |
|
528 * @param e the element to insert |
|
529 * @return <tt>true</tt> (as specified by {@link Deque#offerLast}) |
|
530 * @since 1.6 |
|
531 */ |
|
532 public boolean offerLast(E e) { |
|
533 addLast(e); |
|
534 return true; |
|
535 } |
|
536 |
|
537 /** |
|
538 * Retrieves, but does not remove, the first element of this list, |
|
539 * or returns <tt>null</tt> if this list is empty. |
|
540 * |
|
541 * @return the first element of this list, or <tt>null</tt> |
|
542 * if this list is empty |
|
543 * @since 1.6 |
|
544 */ |
|
545 public E peekFirst() { |
|
546 if (size==0) |
|
547 return null; |
|
548 return getFirst(); |
|
549 } |
|
550 |
|
551 /** |
|
552 * Retrieves, but does not remove, the last element of this list, |
|
553 * or returns <tt>null</tt> if this list is empty. |
|
554 * |
|
555 * @return the last element of this list, or <tt>null</tt> |
|
556 * if this list is empty |
|
557 * @since 1.6 |
|
558 */ |
|
559 public E peekLast() { |
|
560 if (size==0) |
|
561 return null; |
|
562 return getLast(); |
|
563 } |
|
564 |
|
565 /** |
|
566 * Retrieves and removes the first element of this list, |
|
567 * or returns <tt>null</tt> if this list is empty. |
|
568 * |
|
569 * @return the first element of this list, or <tt>null</tt> if |
|
570 * this list is empty |
|
571 * @since 1.6 |
|
572 */ |
|
573 public E pollFirst() { |
|
574 if (size==0) |
|
575 return null; |
|
576 return removeFirst(); |
|
577 } |
|
578 |
|
579 /** |
|
580 * Retrieves and removes the last element of this list, |
|
581 * or returns <tt>null</tt> if this list is empty. |
|
582 * |
|
583 * @return the last element of this list, or <tt>null</tt> if |
|
584 * this list is empty |
|
585 * @since 1.6 |
|
586 */ |
|
587 public E pollLast() { |
|
588 if (size==0) |
|
589 return null; |
|
590 return removeLast(); |
|
591 } |
|
592 |
|
593 /** |
|
594 * Pushes an element onto the stack represented by this list. In other |
|
595 * words, inserts the element at the front of this list. |
|
596 * |
|
597 * <p>This method is equivalent to {@link #addFirst}. |
|
598 * |
|
599 * @param e the element to push |
|
600 * @since 1.6 |
|
601 */ |
|
602 public void push(E e) { |
|
603 addFirst(e); |
|
604 } |
|
605 |
|
606 /** |
|
607 * Pops an element from the stack represented by this list. In other |
|
608 * words, removes and returns the first element of this list. |
|
609 * |
|
610 * <p>This method is equivalent to {@link #removeFirst()}. |
|
611 * |
|
612 * @return the element at the front of this list (which is the top |
|
613 * of the stack represented by this list) |
|
614 * @throws NoSuchElementException if this list is empty |
|
615 * @since 1.6 |
|
616 */ |
|
617 public E pop() { |
|
618 return removeFirst(); |
|
619 } |
|
620 |
|
621 /** |
|
622 * Removes the first occurrence of the specified element in this |
|
623 * list (when traversing the list from head to tail). If the list |
|
624 * does not contain the element, it is unchanged. |
|
625 * |
|
626 * @param o element to be removed from this list, if present |
|
627 * @return <tt>true</tt> if the list contained the specified element |
|
628 * @since 1.6 |
|
629 */ |
|
630 public boolean removeFirstOccurrence(Object o) { |
|
631 return remove(o); |
|
632 } |
|
633 |
|
634 /** |
|
635 * Removes the last occurrence of the specified element in this |
|
636 * list (when traversing the list from head to tail). If the list |
|
637 * does not contain the element, it is unchanged. |
|
638 * |
|
639 * @param o element to be removed from this list, if present |
|
640 * @return <tt>true</tt> if the list contained the specified element |
|
641 * @since 1.6 |
|
642 */ |
|
643 public boolean removeLastOccurrence(Object o) { |
|
644 if (o==null) { |
|
645 for (Entry<E> e = header.previous; e != header; e = e.previous) { |
|
646 if (e.element==null) { |
|
647 remove(e); |
|
648 return true; |
|
649 } |
|
650 } |
|
651 } else { |
|
652 for (Entry<E> e = header.previous; e != header; e = e.previous) { |
|
653 if (o.equals(e.element)) { |
|
654 remove(e); |
|
655 return true; |
|
656 } |
|
657 } |
|
658 } |
|
659 return false; |
|
660 } |
|
661 |
|
662 /** |
|
663 * Returns a list-iterator of the elements in this list (in proper |
|
664 * sequence), starting at the specified position in the list. |
|
665 * Obeys the general contract of <tt>List.listIterator(int)</tt>.<p> |
|
666 * |
|
667 * The list-iterator is <i>fail-fast</i>: if the list is structurally |
|
668 * modified at any time after the Iterator is created, in any way except |
|
669 * through the list-iterator's own <tt>remove</tt> or <tt>add</tt> |
|
670 * methods, the list-iterator will throw a |
|
671 * <tt>ConcurrentModificationException</tt>. Thus, in the face of |
|
672 * concurrent modification, the iterator fails quickly and cleanly, rather |
|
673 * than risking arbitrary, non-deterministic behavior at an undetermined |
|
674 * time in the future. |
|
675 * |
|
676 * @param index index of the first element to be returned from the |
|
677 * list-iterator (by a call to <tt>next</tt>) |
|
678 * @return a ListIterator of the elements in this list (in proper |
|
679 * sequence), starting at the specified position in the list |
|
680 * @throws IndexOutOfBoundsException {@inheritDoc} |
|
681 * @see List#listIterator(int) |
|
682 */ |
|
683 public ListIterator<E> listIterator(int index) { |
|
684 return new ListItr(index); |
|
685 } |
|
686 |
|
687 private class ListItr implements ListIterator<E> { |
|
688 private Entry<E> lastReturned = header; |
|
689 private Entry<E> next; |
|
690 private int nextIndex; |
|
691 private int expectedModCount = modCount; |
|
692 |
|
693 ListItr(int index) { |
|
694 if (index < 0 || index > size) |
|
695 throw new IndexOutOfBoundsException("Index: "+index+ |
|
696 ", Size: "+size); |
|
697 if (index < (size >> 1)) { |
|
698 next = header.next; |
|
699 for (nextIndex=0; nextIndex<index; nextIndex++) |
|
700 next = next.next; |
|
701 } else { |
|
702 next = header; |
|
703 for (nextIndex=size; nextIndex>index; nextIndex--) |
|
704 next = next.previous; |
|
705 } |
|
706 } |
|
707 |
|
708 public boolean hasNext() { |
|
709 return nextIndex != size; |
|
710 } |
|
711 |
|
712 public E next() { |
|
713 checkForComodification(); |
|
714 if (nextIndex == size) |
|
715 throw new NoSuchElementException(); |
|
716 |
|
717 lastReturned = next; |
|
718 next = next.next; |
|
719 nextIndex++; |
|
720 return lastReturned.element; |
|
721 } |
|
722 |
|
723 public boolean hasPrevious() { |
|
724 return nextIndex != 0; |
|
725 } |
|
726 |
|
727 public E previous() { |
|
728 if (nextIndex == 0) |
|
729 throw new NoSuchElementException(); |
|
730 |
|
731 lastReturned = next = next.previous; |
|
732 nextIndex--; |
|
733 checkForComodification(); |
|
734 return lastReturned.element; |
|
735 } |
|
736 |
|
737 public int nextIndex() { |
|
738 return nextIndex; |
|
739 } |
|
740 |
|
741 public int previousIndex() { |
|
742 return nextIndex-1; |
|
743 } |
|
744 |
|
745 public void remove() { |
|
746 checkForComodification(); |
|
747 Entry<E> lastNext = lastReturned.next; |
|
748 try { |
|
749 LinkedList.this.remove(lastReturned); |
|
750 } catch (NoSuchElementException e) { |
|
751 throw new IllegalStateException(); |
|
752 } |
|
753 if (next==lastReturned) |
|
754 next = lastNext; |
|
755 else |
|
756 nextIndex--; |
|
757 lastReturned = header; |
|
758 expectedModCount++; |
|
759 } |
|
760 |
|
761 public void set(E e) { |
|
762 if (lastReturned == header) |
|
763 throw new IllegalStateException(); |
|
764 checkForComodification(); |
|
765 lastReturned.element = e; |
|
766 } |
|
767 |
|
768 public void add(E e) { |
|
769 checkForComodification(); |
|
770 lastReturned = header; |
|
771 addBefore(e, next); |
|
772 nextIndex++; |
|
773 expectedModCount++; |
|
774 } |
|
775 |
|
776 final void checkForComodification() { |
|
777 if (modCount != expectedModCount) |
|
778 throw new ConcurrentModificationException(); |
|
779 } |
|
780 } |
|
781 |
|
782 private static class Entry<E> { |
|
783 E element; |
|
784 Entry<E> next; |
|
785 Entry<E> previous; |
|
786 |
|
787 Entry(E element, Entry<E> next, Entry<E> previous) { |
|
788 this.element = element; |
|
789 this.next = next; |
|
790 this.previous = previous; |
|
791 } |
|
792 } |
|
793 |
|
794 private Entry<E> addBefore(E e, Entry<E> entry) { |
|
795 Entry<E> newEntry = new Entry<E>(e, entry, entry.previous); |
|
796 newEntry.previous.next = newEntry; |
|
797 newEntry.next.previous = newEntry; |
|
798 size++; |
|
799 modCount++; |
|
800 return newEntry; |
|
801 } |
|
802 |
|
803 private E remove(Entry<E> e) { |
|
804 if (e == header) |
|
805 throw new NoSuchElementException(); |
|
806 |
|
807 E result = e.element; |
|
808 e.previous.next = e.next; |
|
809 e.next.previous = e.previous; |
|
810 e.next = e.previous = null; |
|
811 e.element = null; |
|
812 size--; |
|
813 modCount++; |
|
814 return result; |
|
815 } |
|
816 |
|
817 /** |
|
818 * @since 1.6 |
|
819 */ |
|
820 public Iterator<E> descendingIterator() { |
|
821 return new DescendingIterator(); |
|
822 } |
|
823 |
|
824 /** Adapter to provide descending iterators via ListItr.previous */ |
|
825 private class DescendingIterator implements Iterator { |
|
826 final ListItr itr = new ListItr(size()); |
|
827 public boolean hasNext() { |
|
828 return itr.hasPrevious(); |
|
829 } |
|
830 public E next() { |
|
831 return itr.previous(); |
|
832 } |
|
833 public void remove() { |
|
834 itr.remove(); |
|
835 } |
|
836 } |
|
837 |
|
838 /** |
|
839 * Returns a shallow copy of this <tt>LinkedList</tt>. (The elements |
|
840 * themselves are not cloned.) |
|
841 * |
|
842 * @return a shallow copy of this <tt>LinkedList</tt> instance |
|
843 */ |
|
844 public Object clone() { |
|
845 LinkedList<E> clone = null; |
|
846 try { |
|
847 clone = (LinkedList<E>) super.clone(); |
|
848 } catch (CloneNotSupportedException e) { |
|
849 throw new InternalError(); |
|
850 } |
|
851 |
|
852 // Put clone into "virgin" state |
|
853 clone.header = new Entry<E>(null, null, null); |
|
854 clone.header.next = clone.header.previous = clone.header; |
|
855 clone.size = 0; |
|
856 clone.modCount = 0; |
|
857 |
|
858 // Initialize clone with our elements |
|
859 for (Entry<E> e = header.next; e != header; e = e.next) |
|
860 clone.add(e.element); |
|
861 |
|
862 return clone; |
|
863 } |
|
864 |
|
865 /** |
|
866 * Returns an array containing all of the elements in this list |
|
867 * in proper sequence (from first to last element). |
|
868 * |
|
869 * <p>The returned array will be "safe" in that no references to it are |
|
870 * maintained by this list. (In other words, this method must allocate |
|
871 * a new array). The caller is thus free to modify the returned array. |
|
872 * |
|
873 * <p>This method acts as bridge between array-based and collection-based |
|
874 * APIs. |
|
875 * |
|
876 * @return an array containing all of the elements in this list |
|
877 * in proper sequence |
|
878 */ |
|
879 public Object[] toArray() { |
|
880 Object[] result = new Object[size]; |
|
881 int i = 0; |
|
882 for (Entry<E> e = header.next; e != header; e = e.next) |
|
883 result[i++] = e.element; |
|
884 return result; |
|
885 } |
|
886 |
|
887 /** |
|
888 * Returns an array containing all of the elements in this list in |
|
889 * proper sequence (from first to last element); the runtime type of |
|
890 * the returned array is that of the specified array. If the list fits |
|
891 * in the specified array, it is returned therein. Otherwise, a new |
|
892 * array is allocated with the runtime type of the specified array and |
|
893 * the size of this list. |
|
894 * |
|
895 * <p>If the list fits in the specified array with room to spare (i.e., |
|
896 * the array has more elements than the list), the element in the array |
|
897 * immediately following the end of the list is set to <tt>null</tt>. |
|
898 * (This is useful in determining the length of the list <i>only</i> if |
|
899 * the caller knows that the list does not contain any null elements.) |
|
900 * |
|
901 * <p>Like the {@link #toArray()} method, this method acts as bridge between |
|
902 * array-based and collection-based APIs. Further, this method allows |
|
903 * precise control over the runtime type of the output array, and may, |
|
904 * under certain circumstances, be used to save allocation costs. |
|
905 * |
|
906 * <p>Suppose <tt>x</tt> is a list known to contain only strings. |
|
907 * The following code can be used to dump the list into a newly |
|
908 * allocated array of <tt>String</tt>: |
|
909 * |
|
910 * <pre> |
|
911 * String[] y = x.toArray(new String[0]);</pre> |
|
912 * |
|
913 * Note that <tt>toArray(new Object[0])</tt> is identical in function to |
|
914 * <tt>toArray()</tt>. |
|
915 * |
|
916 * @param a the array into which the elements of the list are to |
|
917 * be stored, if it is big enough; otherwise, a new array of the |
|
918 * same runtime type is allocated for this purpose. |
|
919 * @return an array containing the elements of the list |
|
920 * @throws ArrayStoreException if the runtime type of the specified array |
|
921 * is not a supertype of the runtime type of every element in |
|
922 * this list |
|
923 * @throws NullPointerException if the specified array is null |
|
924 */ |
|
925 public <T> T[] toArray(T[] a) { |
|
926 if (a.length < size) |
|
927 a = (T[])java.lang.reflect.Array.newInstance( |
|
928 a.getClass().getComponentType(), size); |
|
929 int i = 0; |
|
930 Object[] result = a; |
|
931 for (Entry<E> e = header.next; e != header; e = e.next) |
|
932 result[i++] = e.element; |
|
933 |
|
934 if (a.length > size) |
|
935 a[size] = null; |
|
936 |
|
937 return a; |
|
938 } |
|
939 |
|
940 private static final long serialVersionUID = 876323262645176354L; |
|
941 |
|
942 /** |
|
943 * Save the state of this <tt>LinkedList</tt> instance to a stream (that |
|
944 * is, serialize it). |
|
945 * |
|
946 * @serialData The size of the list (the number of elements it |
|
947 * contains) is emitted (int), followed by all of its |
|
948 * elements (each an Object) in the proper order. |
|
949 */ |
|
950 private void writeObject(java.io.ObjectOutputStream s) |
|
951 throws java.io.IOException { |
|
952 // Write out any hidden serialization magic |
|
953 s.defaultWriteObject(); |
|
954 |
|
955 // Write out size |
|
956 s.writeInt(size); |
|
957 |
|
958 // Write out all elements in the proper order. |
|
959 for (Entry e = header.next; e != header; e = e.next) |
|
960 s.writeObject(e.element); |
|
961 } |
|
962 |
|
963 /** |
|
964 * Reconstitute this <tt>LinkedList</tt> instance from a stream (that is |
|
965 * deserialize it). |
|
966 */ |
|
967 private void readObject(java.io.ObjectInputStream s) |
|
968 throws java.io.IOException, ClassNotFoundException { |
|
969 // Read in any hidden serialization magic |
|
970 s.defaultReadObject(); |
|
971 |
|
972 // Read in size |
|
973 int size = s.readInt(); |
|
974 |
|
975 // Initialize header |
|
976 header = new Entry<E>(null, null, null); |
|
977 header.next = header.previous = header; |
|
978 |
|
979 // Read in all elements in the proper order. |
|
980 for (int i=0; i<size; i++) |
|
981 addBefore((E)s.readObject(), header); |
|
982 } |
|
983 } |