source: trunk/gcc/libjava/java/util/Collections.java

Last change on this file was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 90.7 KB
Line 
1/* Collections.java -- Utility class with methods to operate on collections
2 Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3
4This file is part of GNU Classpath.
5
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1902111-1307 USA.
20
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library. Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module. An independent module is a module which is not derived from
33or based on this library. If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so. If you do not wish to do so, delete this
36exception statement from your version. */
37
38
39package java.util;
40
41import java.io.Serializable;
42
43/**
44 * Utility class consisting of static methods that operate on, or return
45 * Collections. Contains methods to sort, search, reverse, fill and shuffle
46 * Collections, methods to facilitate interoperability with legacy APIs that
47 * are unaware of collections, a method to return a list which consists of
48 * multiple copies of one element, and methods which "wrap" collections to give
49 * them extra properties, such as thread-safety and unmodifiability.
50 * <p>
51 *
52 * All methods which take a collection throw a {@link NullPointerException} if
53 * that collection is null. Algorithms which can change a collection may, but
54 * are not required, to throw the {@link UnsupportedOperationException} that
55 * the underlying collection would throw during an attempt at modification.
56 * For example,
57 * <code>Collections.singleton("").addAll(Collections.EMPTY_SET)<code>
58 * does not throw a exception, even though addAll is an unsupported operation
59 * on a singleton; the reason for this is that addAll did not attempt to
60 * modify the set.
61 *
62 * @author Original author unknown
63 * @author Eric Blake <ebb9@email.byu.edu>
64 * @see Collection
65 * @see Set
66 * @see List
67 * @see Map
68 * @see Arrays
69 * @since 1.2
70 * @status updated to 1.4
71 */
72public class Collections
73{
74 /**
75 * Constant used to decide cutoff for when a non-RandomAccess list should
76 * be treated as sequential-access. Basically, quadratic behavior is
77 * acceptible for small lists when the overhead is so small in the first
78 * place. I arbitrarily set it to 16, so it may need some tuning.
79 */
80 private static final int LARGE_LIST_SIZE = 16;
81
82 /**
83 * Determines if a list should be treated as a sequential-access one.
84 * Rather than the old method of JDK 1.3 of assuming only instanceof
85 * AbstractSequentialList should be sequential, this uses the new method
86 * of JDK 1.4 of assuming anything that does NOT implement RandomAccess
87 * and exceeds a large (unspecified) size should be sequential.
88 *
89 * @param l the list to check
90 * @return true if it should be treated as sequential-access
91 */
92 private static boolean isSequential(List l)
93 {
94 return ! (l instanceof RandomAccess) && l.size() > LARGE_LIST_SIZE;
95 }
96
97 /**
98 * This class is non-instantiable.
99 */
100 private Collections()
101 {
102 }
103
104 /**
105 * An immutable, serializable, empty Set.
106 * @see Serializable
107 */
108 public static final Set EMPTY_SET = new EmptySet();
109
110 /**
111 * The implementation of {@link #EMPTY_SET}. This class name is required
112 * for compatibility with Sun's JDK serializability.
113 *
114 * @author Eric Blake <ebb9@email.byu.edu>
115 */
116 private static final class EmptySet extends AbstractSet
117 implements Serializable
118 {
119 /**
120 * Compatible with JDK 1.4.
121 */
122 private static final long serialVersionUID = 1582296315990362920L;
123
124 /**
125 * A private constructor adds overhead.
126 */
127 EmptySet()
128 {
129 }
130
131 /**
132 * The size: always 0!
133 */
134 public int size()
135 {
136 return 0;
137 }
138
139 /**
140 * Returns an iterator that does not iterate.
141 */
142 // This is really cheating! I think it's perfectly valid, though.
143 public Iterator iterator()
144 {
145 return EMPTY_LIST.iterator();
146 }
147
148 // The remaining methods are optional, but provide a performance
149 // advantage by not allocating unnecessary iterators in AbstractSet.
150 /**
151 * The empty set never contains anything.
152 */
153 public boolean contains(Object o)
154 {
155 return false;
156 }
157
158 /**
159 * This is true only if the given collection is also empty.
160 */
161 public boolean containsAll(Collection c)
162 {
163 return c.isEmpty();
164 }
165
166 /**
167 * Equal only if the other set is empty.
168 */
169 public boolean equals(Object o)
170 {
171 return o instanceof Set && ((Set) o).isEmpty();
172 }
173
174 /**
175 * The hashcode is always 0.
176 */
177 public int hashCode()
178 {
179 return 0;
180 }
181
182 /**
183 * Always succeeds with false result.
184 */
185 public boolean remove(Object o)
186 {
187 return false;
188 }
189
190 /**
191 * Always succeeds with false result.
192 */
193 public boolean removeAll(Collection c)
194 {
195 return false;
196 }
197
198 /**
199 * Always succeeds with false result.
200 */
201 public boolean retainAll(Collection c)
202 {
203 return false;
204 }
205
206 /**
207 * The array is always empty.
208 */
209 public Object[] toArray()
210 {
211 return new Object[0];
212 }
213
214 /**
215 * We don't even need to use reflection!
216 */
217 public Object[] toArray(Object[] a)
218 {
219 if (a.length > 0)
220 a[0] = null;
221 return a;
222 }
223
224 /**
225 * The string never changes.
226 */
227 public String toString()
228 {
229 return "[]";
230 }
231 } // class EmptySet
232
233 /**
234 * An immutable, serializable, empty List, which implements RandomAccess.
235 * @see Serializable
236 * @see RandomAccess
237 */
238 public static final List EMPTY_LIST = new EmptyList();
239
240 /**
241 * The implementation of {@link #EMPTY_LIST}. This class name is required
242 * for compatibility with Sun's JDK serializability.
243 *
244 * @author Eric Blake <ebb9@email.byu.edu>
245 */
246 private static final class EmptyList extends AbstractList
247 implements Serializable, RandomAccess
248 {
249 /**
250 * Compatible with JDK 1.4.
251 */
252 private static final long serialVersionUID = 8842843931221139166L;
253
254 /**
255 * A private constructor adds overhead.
256 */
257 EmptyList()
258 {
259 }
260
261 /**
262 * The size is always 0.
263 */
264 public int size()
265 {
266 return 0;
267 }
268
269 /**
270 * No matter the index, it is out of bounds.
271 */
272 public Object get(int index)
273 {
274 throw new IndexOutOfBoundsException();
275 }
276
277 // The remaining methods are optional, but provide a performance
278 // advantage by not allocating unnecessary iterators in AbstractList.
279 /**
280 * Never contains anything.
281 */
282 public boolean contains(Object o)
283 {
284 return false;
285 }
286
287 /**
288 * This is true only if the given collection is also empty.
289 */
290 public boolean containsAll(Collection c)
291 {
292 return c.isEmpty();
293 }
294
295 /**
296 * Equal only if the other set is empty.
297 */
298 public boolean equals(Object o)
299 {
300 return o instanceof List && ((List) o).isEmpty();
301 }
302
303 /**
304 * The hashcode is always 1.
305 */
306 public int hashCode()
307 {
308 return 1;
309 }
310
311 /**
312 * Returns -1.
313 */
314 public int indexOf(Object o)
315 {
316 return -1;
317 }
318
319 /**
320 * Returns -1.
321 */
322 public int lastIndexOf(Object o)
323 {
324 return -1;
325 }
326
327 /**
328 * Always succeeds with false result.
329 */
330 public boolean remove(Object o)
331 {
332 return false;
333 }
334
335 /**
336 * Always succeeds with false result.
337 */
338 public boolean removeAll(Collection c)
339 {
340 return false;
341 }
342
343 /**
344 * Always succeeds with false result.
345 */
346 public boolean retainAll(Collection c)
347 {
348 return false;
349 }
350
351 /**
352 * The array is always empty.
353 */
354 public Object[] toArray()
355 {
356 return new Object[0];
357 }
358
359 /**
360 * We don't even need to use reflection!
361 */
362 public Object[] toArray(Object[] a)
363 {
364 if (a.length > 0)
365 a[0] = null;
366 return a;
367 }
368
369 /**
370 * The string never changes.
371 */
372 public String toString()
373 {
374 return "[]";
375 }
376 } // class EmptyList
377
378 /**
379 * An immutable, serializable, empty Map.
380 * @see Serializable
381 */
382 public static final Map EMPTY_MAP = new EmptyMap();
383
384 /**
385 * The implementation of {@link #EMPTY_MAP}. This class name is required
386 * for compatibility with Sun's JDK serializability.
387 *
388 * @author Eric Blake <ebb9@email.byu.edu>
389 */
390 private static final class EmptyMap extends AbstractMap
391 implements Serializable
392 {
393 /**
394 * Compatible with JDK 1.4.
395 */
396 private static final long serialVersionUID = 6428348081105594320L;
397
398 /**
399 * A private constructor adds overhead.
400 */
401 EmptyMap()
402 {
403 }
404
405 /**
406 * There are no entries.
407 */
408 public Set entrySet()
409 {
410 return EMPTY_SET;
411 }
412
413 // The remaining methods are optional, but provide a performance
414 // advantage by not allocating unnecessary iterators in AbstractMap.
415 /**
416 * No entries!
417 */
418 public boolean containsKey(Object key)
419 {
420 return false;
421 }
422
423 /**
424 * No entries!
425 */
426 public boolean containsValue(Object value)
427 {
428 return false;
429 }
430
431 /**
432 * Equal to all empty maps.
433 */
434 public boolean equals(Object o)
435 {
436 return o instanceof Map && ((Map) o).isEmpty();
437 }
438
439 /**
440 * No mappings, so this returns null.
441 */
442 public Object get(Object o)
443 {
444 return null;
445 }
446
447 /**
448 * The hashcode is always 0.
449 */
450 public int hashCode()
451 {
452 return 0;
453 }
454
455 /**
456 * No entries.
457 */
458 public Set keySet()
459 {
460 return EMPTY_SET;
461 }
462
463 /**
464 * Remove always succeeds, with null result.
465 */
466 public Object remove(Object o)
467 {
468 return null;
469 }
470
471 /**
472 * Size is always 0.
473 */
474 public int size()
475 {
476 return 0;
477 }
478
479 /**
480 * No entries. Technically, EMPTY_SET, while more specific than a general
481 * Collection, will work. Besides, that's what the JDK uses!
482 */
483 public Collection values()
484 {
485 return EMPTY_SET;
486 }
487
488 /**
489 * The string never changes.
490 */
491 public String toString()
492 {
493 return "[]";
494 }
495 } // class EmptyMap
496
497
498
499 /**
500 * Compare two objects with or without a Comparator. If c is null, uses the
501 * natural ordering. Slightly slower than doing it inline if the JVM isn't
502 * clever, but worth it for removing a duplicate of the search code.
503 * Note: This code is also used in Arrays (for sort as well as search).
504 */
505 static final int compare(Object o1, Object o2, Comparator c)
506 {
507 return c == null ? ((Comparable) o1).compareTo(o2) : c.compare(o1, o2);
508 }
509
510 /**
511 * Perform a binary search of a List for a key, using the natural ordering of
512 * the elements. The list must be sorted (as by the sort() method) - if it is
513 * not, the behavior of this method is undefined, and may be an infinite
514 * loop. Further, the key must be comparable with every item in the list. If
515 * the list contains the key more than once, any one of them may be found.
516 * <p>
517 *
518 * This algorithm behaves in log(n) time for {@link RandomAccess} lists,
519 * and uses a linear search with O(n) link traversals and log(n) comparisons
520 * with {@link AbstractSequentialList} lists. Note: although the
521 * specification allows for an infinite loop if the list is unsorted, it will
522 * not happen in this (Classpath) implementation.
523 *
524 * @param l the list to search (must be sorted)
525 * @param key the value to search for
526 * @return the index at which the key was found, or -n-1 if it was not
527 * found, where n is the index of the first value higher than key or
528 * a.length if there is no such value
529 * @throws ClassCastException if key could not be compared with one of the
530 * elements of l
531 * @throws NullPointerException if a null element has compareTo called
532 * @see #sort(List)
533 */
534 public static int binarySearch(List l, Object key)
535 {
536 return binarySearch(l, key, null);
537 }
538
539 /**
540 * Perform a binary search of a List for a key, using a supplied Comparator.
541 * The list must be sorted (as by the sort() method with the same Comparator)
542 * - if it is not, the behavior of this method is undefined, and may be an
543 * infinite loop. Further, the key must be comparable with every item in the
544 * list. If the list contains the key more than once, any one of them may be
545 * found. If the comparator is null, the elements' natural ordering is used.
546 * <p>
547 *
548 * This algorithm behaves in log(n) time for {@link RandomAccess} lists,
549 * and uses a linear search with O(n) link traversals and log(n) comparisons
550 * with {@link AbstractSequentialList} lists. Note: although the
551 * specification allows for an infinite loop if the list is unsorted, it will
552 * not happen in this (Classpath) implementation.
553 *
554 * @param l the list to search (must be sorted)
555 * @param key the value to search for
556 * @param c the comparator by which the list is sorted
557 * @return the index at which the key was found, or -n-1 if it was not
558 * found, where n is the index of the first value higher than key or
559 * a.length if there is no such value
560 * @throws ClassCastException if key could not be compared with one of the
561 * elements of l
562 * @throws NullPointerException if a null element is compared with natural
563 * ordering (only possible when c is null)
564 * @see #sort(List, Comparator)
565 */
566 public static int binarySearch(List l, Object key, Comparator c)
567 {
568 int pos = 0;
569 int low = 0;
570 int hi = l.size() - 1;
571
572 // We use a linear search with log(n) comparisons using an iterator
573 // if the list is sequential-access.
574 if (isSequential(l))
575 {
576 ListIterator itr = l.listIterator();
577 int i = 0;
578 while (low <= hi)
579 {
580 pos = (low + hi) >> 1;
581 if (i < pos)
582 for ( ; i != pos; i++, itr.next());
583 else
584 for ( ; i != pos; i--, itr.previous());
585 final int d = compare(key, itr.next(), c);
586 if (d == 0)
587 return pos;
588 else if (d < 0)
589 hi = pos - 1;
590 else
591 // This gets the insertion point right on the last loop
592 low = ++pos;
593 }
594 }
595 else
596 {
597 while (low <= hi)
598 {
599 pos = (low + hi) >> 1;
600 final int d = compare(key, l.get(pos), c);
601 if (d == 0)
602 return pos;
603 else if (d < 0)
604 hi = pos - 1;
605 else
606 // This gets the insertion point right on the last loop
607 low = ++pos;
608 }
609 }
610
611 // If we failed to find it, we do the same whichever search we did.
612 return -pos - 1;
613 }
614
615 /**
616 * Copy one list to another. If the destination list is longer than the
617 * source list, the remaining elements are unaffected. This method runs in
618 * linear time.
619 *
620 * @param dest the destination list
621 * @param source the source list
622 * @throws IndexOutOfBoundsException if the destination list is shorter
623 * than the source list (the destination will be unmodified)
624 * @throws UnsupportedOperationException if dest.listIterator() does not
625 * support the set operation
626 */
627 public static void copy(List dest, List source)
628 {
629 int pos = source.size();
630 if (dest.size() < pos)
631 throw new IndexOutOfBoundsException("Source does not fit in dest");
632
633 Iterator i1 = source.iterator();
634 ListIterator i2 = dest.listIterator();
635
636 while (--pos >= 0)
637 {
638 i2.next();
639 i2.set(i1.next());
640 }
641 }
642
643 /**
644 * Returns an Enumeration over a collection. This allows interoperability
645 * with legacy APIs that require an Enumeration as input.
646 *
647 * @param c the Collection to iterate over
648 * @return an Enumeration backed by an Iterator over c
649 */
650 public static Enumeration enumeration(Collection c)
651 {
652 final Iterator i = c.iterator();
653 return new Enumeration()
654 {
655 public final boolean hasMoreElements()
656 {
657 return i.hasNext();
658 }
659 public final Object nextElement()
660 {
661 return i.next();
662 }
663 };
664 }
665
666 /**
667 * Replace every element of a list with a given value. This method runs in
668 * linear time.
669 *
670 * @param l the list to fill.
671 * @param val the object to vill the list with.
672 * @throws UnsupportedOperationException if l.listIterator() does not
673 * support the set operation.
674 */
675 public static void fill(List l, Object val)
676 {
677 ListIterator itr = l.listIterator();
678 for (int i = l.size() - 1; i >= 0; --i)
679 {
680 itr.next();
681 itr.set(val);
682 }
683 }
684
685 /**
686 * Returns the starting index where the specified sublist first occurs
687 * in a larger list, or -1 if there is no matching position. If
688 * <code>target.size() &gt; source.size()</code>, this returns -1,
689 * otherwise this implementation uses brute force, checking for
690 * <code>source.sublist(i, i + target.size()).equals(target)</code>
691 * for all possible i.
692 *
693 * @param source the list to search
694 * @param target the sublist to search for
695 * @return the index where found, or -1
696 * @since 1.4
697 */
698 public static int indexOfSubList(List source, List target)
699 {
700 int ssize = source.size();
701 for (int i = 0, j = target.size(); j <= ssize; i++, j++)
702 if (source.subList(i, j).equals(target))
703 return i;
704 return -1;
705 }
706
707 /**
708 * Returns the starting index where the specified sublist last occurs
709 * in a larger list, or -1 if there is no matching position. If
710 * <code>target.size() &gt; source.size()</code>, this returns -1,
711 * otherwise this implementation uses brute force, checking for
712 * <code>source.sublist(i, i + target.size()).equals(target)</code>
713 * for all possible i.
714 *
715 * @param source the list to search
716 * @param target the sublist to search for
717 * @return the index where found, or -1
718 * @since 1.4
719 */
720 public static int lastIndexOfSubList(List source, List target)
721 {
722 int ssize = source.size();
723 for (int i = ssize - target.size(), j = ssize; i >= 0; i--, j--)
724 if (source.subList(i, j).equals(target))
725 return i;
726 return -1;
727 }
728
729 /**
730 * Returns an ArrayList holding the elements visited by a given
731 * Enumeration. This method exists for interoperability between legacy
732 * APIs and the new Collection API.
733 *
734 * @param e the enumeration to put in a list
735 * @return a list containing the enumeration elements
736 * @see ArrayList
737 * @since 1.4
738 */
739 public static ArrayList list(Enumeration e)
740 {
741 ArrayList l = new ArrayList();
742 while (e.hasMoreElements())
743 l.add(e.nextElement());
744 return l;
745 }
746
747 /**
748 * Find the maximum element in a Collection, according to the natural
749 * ordering of the elements. This implementation iterates over the
750 * Collection, so it works in linear time.
751 *
752 * @param c the Collection to find the maximum element of
753 * @return the maximum element of c
754 * @exception NoSuchElementException if c is empty
755 * @exception ClassCastException if elements in c are not mutually comparable
756 * @exception NullPointerException if null.compareTo is called
757 */
758 public static Object max(Collection c)
759 {
760 return max(c, null);
761 }
762
763 /**
764 * Find the maximum element in a Collection, according to a specified
765 * Comparator. This implementation iterates over the Collection, so it
766 * works in linear time.
767 *
768 * @param c the Collection to find the maximum element of
769 * @param order the Comparator to order the elements by, or null for natural
770 * ordering
771 * @return the maximum element of c
772 * @throws NoSuchElementException if c is empty
773 * @throws ClassCastException if elements in c are not mutually comparable
774 * @throws NullPointerException if null is compared by natural ordering
775 * (only possible when order is null)
776 */
777 public static Object max(Collection c, Comparator order)
778 {
779 Iterator itr = c.iterator();
780 Object max = itr.next(); // throws NoSuchElementException
781 int csize = c.size();
782 for (int i = 1; i < csize; i++)
783 {
784 Object o = itr.next();
785 if (compare(max, o, order) < 0)
786 max = o;
787 }
788 return max;
789 }
790
791 /**
792 * Find the minimum element in a Collection, according to the natural
793 * ordering of the elements. This implementation iterates over the
794 * Collection, so it works in linear time.
795 *
796 * @param c the Collection to find the minimum element of
797 * @return the minimum element of c
798 * @throws NoSuchElementException if c is empty
799 * @throws ClassCastException if elements in c are not mutually comparable
800 * @throws NullPointerException if null.compareTo is called
801 */
802 public static Object min(Collection c)
803 {
804 return min(c, null);
805 }
806
807 /**
808 * Find the minimum element in a Collection, according to a specified
809 * Comparator. This implementation iterates over the Collection, so it
810 * works in linear time.
811 *
812 * @param c the Collection to find the minimum element of
813 * @param order the Comparator to order the elements by, or null for natural
814 * ordering
815 * @return the minimum element of c
816 * @throws NoSuchElementException if c is empty
817 * @throws ClassCastException if elements in c are not mutually comparable
818 * @throws NullPointerException if null is compared by natural ordering
819 * (only possible when order is null)
820 */
821 public static Object min(Collection c, Comparator order)
822 {
823 Iterator itr = c.iterator();
824 Object min = itr.next(); // throws NoSuchElementExcception
825 int csize = c.size();
826 for (int i = 1; i < csize; i++)
827 {
828 Object o = itr.next();
829 if (compare(min, o, order) > 0)
830 min = o;
831 }
832 return min;
833 }
834
835 /**
836 * Creates an immutable list consisting of the same object repeated n times.
837 * The returned object is tiny, consisting of only a single reference to the
838 * object and a count of the number of elements. It is Serializable, and
839 * implements RandomAccess. You can use it in tandem with List.addAll for
840 * fast list construction.
841 *
842 * @param n the number of times to repeat the object
843 * @param o the object to repeat
844 * @return a List consisting of n copies of o
845 * @throws IllegalArgumentException if n &lt; 0
846 * @see List#addAll(Collection)
847 * @see Serializable
848 * @see RandomAccess
849 */
850 public static List nCopies(final int n, final Object o)
851 {
852 return new CopiesList(n, o);
853 }
854
855 /**
856 * The implementation of {@link #nCopies(int, Object)}. This class name
857 * is required for compatibility with Sun's JDK serializability.
858 *
859 * @author Eric Blake <ebb9@email.byu.edu>
860 */
861 private static final class CopiesList extends AbstractList
862 implements Serializable, RandomAccess
863 {
864 /**
865 * Compatible with JDK 1.4.
866 */
867 private static final long serialVersionUID = 2739099268398711800L;
868
869 /**
870 * The count of elements in this list.
871 * @serial the list size
872 */
873 private final int n;
874
875 /**
876 * The repeated list element.
877 * @serial the list contents
878 */
879 private final Object element;
880
881 /**
882 * Constructs the list.
883 *
884 * @param n the count
885 * @param o the object
886 * @throws IllegalArgumentException if n &lt; 0
887 */
888 CopiesList(int n, Object o)
889 {
890 if (n < 0)
891 throw new IllegalArgumentException();
892 this.n = n;
893 element = o;
894 }
895
896 /**
897 * The size is fixed.
898 */
899 public int size()
900 {
901 return n;
902 }
903
904 /**
905 * The same element is returned.
906 */
907 public Object get(int index)
908 {
909 if (index < 0 || index >= n)
910 throw new IndexOutOfBoundsException();
911 return element;
912 }
913
914 // The remaining methods are optional, but provide a performance
915 // advantage by not allocating unnecessary iterators in AbstractList.
916 /**
917 * This list only contains one element.
918 */
919 public boolean contains(Object o)
920 {
921 return n > 0 && equals(o, element);
922 }
923
924 /**
925 * The index is either 0 or -1.
926 */
927 public int indexOf(Object o)
928 {
929 return (n > 0 && equals(o, element)) ? 0 : -1;
930 }
931
932 /**
933 * The index is either n-1 or -1.
934 */
935 public int lastIndexOf(Object o)
936 {
937 return equals(o, element) ? n - 1 : -1;
938 }
939
940 /**
941 * A subList is just another CopiesList.
942 */
943 public List subList(int from, int to)
944 {
945 if (from < 0 || to > n)
946 throw new IndexOutOfBoundsException();
947 return new CopiesList(to - from, element);
948 }
949
950 /**
951 * The array is easy.
952 */
953 public Object[] toArray()
954 {
955 Object[] a = new Object[n];
956 Arrays.fill(a, element);
957 return a;
958 }
959
960 /**
961 * The string is easy to generate.
962 */
963 public String toString()
964 {
965 StringBuffer r = new StringBuffer("{");
966 for (int i = n - 1; --i > 0; )
967 r.append(element).append(", ");
968 r.append(element).append("}");
969 return r.toString();
970 }
971 } // class CopiesList
972
973 /**
974 * Replace all instances of one object with another in the specified list.
975 * The list does not change size. An element e is replaced if
976 * <code>oldval == null ? e == null : oldval.equals(e)</code>.
977 *
978 * @param list the list to iterate over
979 * @param oldval the element to replace
980 * @param newval the new value for the element
981 * @return true if a replacement occurred
982 * @throws UnsupportedOperationException if the list iterator does not allow
983 * for the set operation
984 * @throws ClassCastException newval is of a type which cannot be added
985 * to the list
986 * @throws IllegalArgumentException some other aspect of newval stops
987 * it being added to the list
988 * @since 1.4
989 */
990 public static boolean replaceAll(List list, Object oldval, Object newval)
991 {
992 ListIterator itr = list.listIterator();
993 boolean replace_occured = false;
994 for (int i = list.size(); --i >= 0; )
995 if (AbstractCollection.equals(oldval, itr.next()))
996 {
997 itr.set(newval);
998 replace_occured = true;
999 }
1000 return replace_occured;
1001 }
1002
1003 /**
1004 * Reverse a given list. This method works in linear time.
1005 *
1006 * @param l the list to reverse
1007 * @throws UnsupportedOperationException if l.listIterator() does not
1008 * support the set operation
1009 */
1010 public static void reverse(List l)
1011 {
1012 ListIterator i1 = l.listIterator();
1013 int pos1 = 1;
1014 int pos2 = l.size();
1015 ListIterator i2 = l.listIterator(pos2);
1016 while (pos1 < pos2)
1017 {
1018 Object o = i1.next();
1019 i1.set(i2.previous());
1020 i2.set(o);
1021 ++pos1;
1022 --pos2;
1023 }
1024 }
1025
1026 /**
1027 * Get a comparator that implements the reverse of natural ordering. In
1028 * other words, this sorts Comparable objects opposite of how their
1029 * compareTo method would sort. This makes it easy to sort into reverse
1030 * order, by simply passing Collections.reverseOrder() to the sort method.
1031 * The return value of this method is Serializable.
1032 *
1033 * @return a comparator that imposes reverse natural ordering
1034 * @see Comparable
1035 * @see Serializable
1036 */
1037 public static Comparator reverseOrder()
1038 {
1039 return rcInstance;
1040 }
1041
1042 /**
1043 * The object for {@link #reverseOrder()}.
1044 */
1045 static private final ReverseComparator rcInstance = new ReverseComparator();
1046
1047 /**
1048 * The implementation of {@link #reverseOrder()}. This class name
1049 * is required for compatibility with Sun's JDK serializability.
1050 *
1051 * @author Eric Blake <ebb9@email.byu.edu>
1052 */
1053 private static final class ReverseComparator
1054 implements Comparator, Serializable
1055 {
1056 /**
1057 * Compatible with JDK 1.4.
1058 */
1059 static private final long serialVersionUID = 7207038068494060240L;
1060
1061 /**
1062 * A private constructor adds overhead.
1063 */
1064 ReverseComparator()
1065 {
1066 }
1067
1068 /**
1069 * Compare two objects in reverse natural order.
1070 *
1071 * @param a the first object
1072 * @param b the second object
1073 * @return &lt;, ==, or &gt; 0 according to b.compareTo(a)
1074 */
1075 public int compare(Object a, Object b)
1076 {
1077 return ((Comparable) b).compareTo(a);
1078 }
1079 }
1080
1081 /**
1082 * Rotate the elements in a list by a specified distance. After calling this
1083 * method, the element now at index <code>i</code> was formerly at index
1084 * <code>(i - distance) mod list.size()</code>. The list size is unchanged.
1085 * <p>
1086 *
1087 * For example, suppose a list contains <code>[t, a, n, k, s]</code>. After
1088 * either <code>Collections.rotate(l, 4)</code> or
1089 * <code>Collections.rotate(l, -1)</code>, the new contents are
1090 * <code>[s, t, a, n, k]</code>. This can be applied to sublists to rotate
1091 * just a portion of the list. For example, to move element <code>a</code>
1092 * forward two positions in the original example, use
1093 * <code>Collections.rotate(l.subList(1, 3+1), -1)</code>, which will
1094 * result in <code>[t, n, k, a, s]</code>.
1095 * <p>
1096 *
1097 * If the list is small or implements {@link RandomAccess}, the
1098 * implementation exchanges the first element to its destination, then the
1099 * displaced element, and so on until a circuit has been completed. The
1100 * process is repeated if needed on the second element, and so forth, until
1101 * all elements have been swapped. For large non-random lists, the
1102 * implementation breaks the list into two sublists at index
1103 * <code>-distance mod size</code>, calls {@link #reverse(List)} on the
1104 * pieces, then reverses the overall list.
1105 *
1106 * @param list the list to rotate
1107 * @param distance the distance to rotate by; unrestricted in value
1108 * @throws UnsupportedOperationException if the list does not support set
1109 * @since 1.4
1110 */
1111 public static void rotate(List list, int distance)
1112 {
1113 int size = list.size();
1114 distance %= size;
1115 if (distance == 0)
1116 return;
1117 if (distance < 0)
1118 distance += size;
1119
1120 if (isSequential(list))
1121 {
1122 reverse(list);
1123 reverse(list.subList(0, distance));
1124 reverse(list.subList(distance, size));
1125 }
1126 else
1127 {
1128 // Determine the least common multiple of distance and size, as there
1129 // are (distance / LCM) loops to cycle through.
1130 int a = size;
1131 int lcm = distance;
1132 int b = a % lcm;
1133 while (b != 0)
1134 {
1135 a = lcm;
1136 lcm = b;
1137 b = a % lcm;
1138 }
1139
1140 // Now, make the swaps. We must take the remainder every time through
1141 // the inner loop so that we don't overflow i to negative values.
1142 while (--lcm >= 0)
1143 {
1144 Object o = list.get(lcm);
1145 for (int i = lcm + distance; i != lcm; i = (i + distance) % size)
1146 o = list.set(i, o);
1147 list.set(lcm, o);
1148 }
1149 }
1150 }
1151
1152 /**
1153 * Shuffle a list according to a default source of randomness. The algorithm
1154 * used iterates backwards over the list, swapping each element with an
1155 * element randomly selected from the elements in positions less than or
1156 * equal to it (using r.nextInt(int)).
1157 * <p>
1158 *
1159 * This algorithm would result in a perfectly fair shuffle (that is, each
1160 * element would have an equal chance of ending up in any position) if r were
1161 * a perfect source of randomness. In practice the results are merely very
1162 * close to perfect.
1163 * <p>
1164 *
1165 * This method operates in linear time. To do this on large lists which do
1166 * not implement {@link RandomAccess}, a temporary array is used to acheive
1167 * this speed, since it would be quadratic access otherwise.
1168 *
1169 * @param l the list to shuffle
1170 * @throws UnsupportedOperationException if l.listIterator() does not
1171 * support the set operation
1172 */
1173 public static void shuffle(List l)
1174 {
1175 if (defaultRandom == null)
1176 {
1177 synchronized (Collections.class)
1178 {
1179 if (defaultRandom == null)
1180 defaultRandom = new Random();
1181 }
1182 }
1183 shuffle(l, defaultRandom);
1184 }
1185
1186 /**
1187 * Cache a single Random object for use by shuffle(List). This improves
1188 * performance as well as ensuring that sequential calls to shuffle() will
1189 * not result in the same shuffle order occurring: the resolution of
1190 * System.currentTimeMillis() is not sufficient to guarantee a unique seed.
1191 */
1192 private static Random defaultRandom = null;
1193
1194 /**
1195 * Shuffle a list according to a given source of randomness. The algorithm
1196 * used iterates backwards over the list, swapping each element with an
1197 * element randomly selected from the elements in positions less than or
1198 * equal to it (using r.nextInt(int)).
1199 * <p>
1200 *
1201 * This algorithm would result in a perfectly fair shuffle (that is, each
1202 * element would have an equal chance of ending up in any position) if r were
1203 * a perfect source of randomness. In practise (eg if r = new Random()) the
1204 * results are merely very close to perfect.
1205 * <p>
1206 *
1207 * This method operates in linear time. To do this on large lists which do
1208 * not implement {@link RandomAccess}, a temporary array is used to acheive
1209 * this speed, since it would be quadratic access otherwise.
1210 *
1211 * @param l the list to shuffle
1212 * @param r the source of randomness to use for the shuffle
1213 * @throws UnsupportedOperationException if l.listIterator() does not
1214 * support the set operation
1215 */
1216 public static void shuffle(List l, Random r)
1217 {
1218 int lsize = l.size();
1219 ListIterator i = l.listIterator(lsize);
1220 boolean sequential = isSequential(l);
1221 Object[] a = null; // stores a copy of the list for the sequential case
1222
1223 if (sequential)
1224 a = l.toArray();
1225
1226 for (int pos = lsize - 1; pos > 0; --pos)
1227 {
1228 // Obtain a random position to swap with. pos + 1 is used so that the
1229 // range of the random number includes the current position.
1230 int swap = r.nextInt(pos + 1);
1231
1232 // Swap the desired element.
1233 Object o;
1234 if (sequential)
1235 {
1236 o = a[swap];
1237 a[swap] = i.previous();
1238 }
1239 else
1240 o = l.set(swap, i.previous());
1241
1242 i.set(o);
1243 }
1244 }
1245
1246
1247
1248 /**
1249 * Obtain an immutable Set consisting of a single element. The return value
1250 * of this method is Serializable.
1251 *
1252 * @param o the single element
1253 * @return an immutable Set containing only o
1254 * @see Serializable
1255 */
1256 public static Set singleton(Object o)
1257 {
1258 return new SingletonSet(o);
1259 }
1260
1261 /**
1262 * The implementation of {@link #singleton(Object)}. This class name
1263 * is required for compatibility with Sun's JDK serializability.
1264 *
1265 * @author Eric Blake <ebb9@email.byu.edu>
1266 */
1267 private static final class SingletonSet extends AbstractSet
1268 implements Serializable
1269 {
1270 /**
1271 * Compatible with JDK 1.4.
1272 */
1273 private static final long serialVersionUID = 3193687207550431679L;
1274
1275
1276 /**
1277 * The single element; package visible for use in nested class.
1278 * @serial the singleton
1279 */
1280 final Object element;
1281
1282 /**
1283 * Construct a singleton.
1284 * @param o the element
1285 */
1286 SingletonSet(Object o)
1287 {
1288 element = o;
1289 }
1290
1291 /**
1292 * The size: always 1!
1293 */
1294 public int size()
1295 {
1296 return 1;
1297 }
1298
1299 /**
1300 * Returns an iterator over the lone element.
1301 */
1302 public Iterator iterator()
1303 {
1304 return new Iterator()
1305 {
1306 private boolean hasNext = true;
1307
1308 public boolean hasNext()
1309 {
1310 return hasNext;
1311 }
1312
1313 public Object next()
1314 {
1315 if (hasNext)
1316 {
1317 hasNext = false;
1318 return element;
1319 }
1320 else
1321 throw new NoSuchElementException();
1322 }
1323
1324 public void remove()
1325 {
1326 throw new UnsupportedOperationException();
1327 }
1328 };
1329 }
1330
1331 // The remaining methods are optional, but provide a performance
1332 // advantage by not allocating unnecessary iterators in AbstractSet.
1333 /**
1334 * The set only contains one element.
1335 */
1336 public boolean contains(Object o)
1337 {
1338 return equals(o, element);
1339 }
1340
1341 /**
1342 * This is true if the other collection only contains the element.
1343 */
1344 public boolean containsAll(Collection c)
1345 {
1346 Iterator i = c.iterator();
1347 int pos = c.size();
1348 while (--pos >= 0)
1349 if (! equals(i.next(), element))
1350 return false;
1351 return true;
1352 }
1353
1354 /**
1355 * The hash is just that of the element.
1356 */
1357 public int hashCode()
1358 {
1359 return hashCode(element);
1360 }
1361
1362 /**
1363 * Returning an array is simple.
1364 */
1365 public Object[] toArray()
1366 {
1367 return new Object[] {element};
1368 }
1369
1370 /**
1371 * Obvious string.
1372 */
1373 public String toString()
1374 {
1375 return "[" + element + "]";
1376 }
1377 } // class SingletonSet
1378
1379 /**
1380 * Obtain an immutable List consisting of a single element. The return value
1381 * of this method is Serializable, and implements RandomAccess.
1382 *
1383 * @param o the single element
1384 * @return an immutable List containing only o
1385 * @see Serializable
1386 * @see RandomAccess
1387 * @since 1.3
1388 */
1389 public static List singletonList(Object o)
1390 {
1391 return new SingletonList(o);
1392 }
1393
1394 /**
1395 * The implementation of {@link #singletonList(Object)}. This class name
1396 * is required for compatibility with Sun's JDK serializability.
1397 *
1398 * @author Eric Blake <ebb9@email.byu.edu>
1399 */
1400 private static final class SingletonList extends AbstractList
1401 implements Serializable, RandomAccess
1402 {
1403 /**
1404 * Compatible with JDK 1.4.
1405 */
1406 private static final long serialVersionUID = 3093736618740652951L;
1407
1408 /**
1409 * The single element.
1410 * @serial the singleton
1411 */
1412 private final Object element;
1413
1414 /**
1415 * Construct a singleton.
1416 * @param o the element
1417 */
1418 SingletonList(Object o)
1419 {
1420 element = o;
1421 }
1422
1423 /**
1424 * The size: always 1!
1425 */
1426 public int size()
1427 {
1428 return 1;
1429 }
1430
1431 /**
1432 * Only index 0 is valid.
1433 */
1434 public Object get(int index)
1435 {
1436 if (index == 0)
1437 return element;
1438 throw new IndexOutOfBoundsException();
1439 }
1440
1441 // The remaining methods are optional, but provide a performance
1442 // advantage by not allocating unnecessary iterators in AbstractList.
1443 /**
1444 * The set only contains one element.
1445 */
1446 public boolean contains(Object o)
1447 {
1448 return equals(o, element);
1449 }
1450
1451 /**
1452 * This is true if the other collection only contains the element.
1453 */
1454 public boolean containsAll(Collection c)
1455 {
1456 Iterator i = c.iterator();
1457 int pos = c.size();
1458 while (--pos >= 0)
1459 if (! equals(i.next(), element))
1460 return false;
1461 return true;
1462 }
1463
1464 /**
1465 * Speed up the hashcode computation.
1466 */
1467 public int hashCode()
1468 {
1469 return 31 + hashCode(element);
1470 }
1471
1472 /**
1473 * Either the list has it or not.
1474 */
1475 public int indexOf(Object o)
1476 {
1477 return equals(o, element) ? 0 : -1;
1478 }
1479
1480 /**
1481 * Either the list has it or not.
1482 */
1483 public int lastIndexOf(Object o)
1484 {
1485 return equals(o, element) ? 0 : -1;
1486 }
1487
1488 /**
1489 * Sublists are limited in scope.
1490 */
1491 public List subList(int from, int to)
1492 {
1493 if (from == to && (to == 0 || to == 1))
1494 return EMPTY_LIST;
1495 if (from == 0 && to == 1)
1496 return this;
1497 if (from > to)
1498 throw new IllegalArgumentException();
1499 throw new IndexOutOfBoundsException();
1500 }
1501
1502 /**
1503 * Returning an array is simple.
1504 */
1505 public Object[] toArray()
1506 {
1507 return new Object[] {element};
1508 }
1509
1510 /**
1511 * Obvious string.
1512 */
1513 public String toString()
1514 {
1515 return "[" + element + "]";
1516 }
1517 } // class SingletonList
1518
1519 /**
1520 * Obtain an immutable Map consisting of a single key-value pair.
1521 * The return value of this method is Serializable.
1522 *
1523 * @param key the single key
1524 * @param value the single value
1525 * @return an immutable Map containing only the single key-value pair
1526 * @see Serializable
1527 * @since 1.3
1528 */
1529 public static Map singletonMap(Object key, Object value)
1530 {
1531 return new SingletonMap(key, value);
1532 }
1533
1534 /**
1535 * The implementation of {@link #singletonMap(Object)}. This class name
1536 * is required for compatibility with Sun's JDK serializability.
1537 *
1538 * @author Eric Blake <ebb9@email.byu.edu>
1539 */
1540 private static final class SingletonMap extends AbstractMap
1541 implements Serializable
1542 {
1543 /**
1544 * Compatible with JDK 1.4.
1545 */
1546 private static final long serialVersionUID = -6979724477215052911L;
1547
1548 /**
1549 * The single key.
1550 * @serial the singleton key
1551 */
1552 private final Object k;
1553
1554 /**
1555 * The corresponding value.
1556 * @serial the singleton value
1557 */
1558 private final Object v;
1559
1560 /**
1561 * Cache the entry set.
1562 */
1563 private transient Set entries;
1564
1565 /**
1566 * Construct a singleton.
1567 * @param key the key
1568 * @param value the value
1569 */
1570 SingletonMap(Object key, Object value)
1571 {
1572 k = key;
1573 v = value;
1574 }
1575
1576 /**
1577 * There is a single immutable entry.
1578 */
1579 public Set entrySet()
1580 {
1581 if (entries == null)
1582 entries = singleton(new AbstractMap.BasicMapEntry(k, v)
1583 {
1584 public Object setValue(Object o)
1585 {
1586 throw new UnsupportedOperationException();
1587 }
1588 });
1589 return entries;
1590 }
1591
1592 // The remaining methods are optional, but provide a performance
1593 // advantage by not allocating unnecessary iterators in AbstractMap.
1594 /**
1595 * Single entry.
1596 */
1597 public boolean containsKey(Object key)
1598 {
1599 return equals(key, k);
1600 }
1601
1602 /**
1603 * Single entry.
1604 */
1605 public boolean containsValue(Object value)
1606 {
1607 return equals(value, v);
1608 }
1609
1610 /**
1611 * Single entry.
1612 */
1613 public Object get(Object key)
1614 {
1615 return equals(key, k) ? v : null;
1616 }
1617
1618 /**
1619 * Calculate the hashcode directly.
1620 */
1621 public int hashCode()
1622 {
1623 return hashCode(k) ^ hashCode(v);
1624 }
1625
1626 /**
1627 * Return the keyset.
1628 */
1629 public Set keySet()
1630 {
1631 if (keys == null)
1632 keys = singleton(k);
1633 return keys;
1634 }
1635
1636 /**
1637 * The size: always 1!
1638 */
1639 public int size()
1640 {
1641 return 1;
1642 }
1643
1644 /**
1645 * Return the values. Technically, a singleton, while more specific than
1646 * a general Collection, will work. Besides, that's what the JDK uses!
1647 */
1648 public Collection values()
1649 {
1650 if (values == null)
1651 values = singleton(v);
1652 return values;
1653 }
1654
1655 /**
1656 * Obvious string.
1657 */
1658 public String toString()
1659 {
1660 return "{" + k + "=" + v + "}";
1661 }
1662 } // class SingletonMap
1663
1664 /**
1665 * Sort a list according to the natural ordering of its elements. The list
1666 * must be modifiable, but can be of fixed size. The sort algorithm is
1667 * precisely that used by Arrays.sort(Object[]), which offers guaranteed
1668 * nlog(n) performance. This implementation dumps the list into an array,
1669 * sorts the array, and then iterates over the list setting each element from
1670 * the array.
1671 *
1672 * @param l the List to sort
1673 * @throws ClassCastException if some items are not mutually comparable
1674 * @throws UnsupportedOperationException if the List is not modifiable
1675 * @throws NullPointerException if some element is null
1676 * @see Arrays#sort(Object[])
1677 */
1678 public static void sort(List l)
1679 {
1680 sort(l, null);
1681 }
1682
1683 /**
1684 * Sort a list according to a specified Comparator. The list must be
1685 * modifiable, but can be of fixed size. The sort algorithm is precisely that
1686 * used by Arrays.sort(Object[], Comparator), which offers guaranteed
1687 * nlog(n) performance. This implementation dumps the list into an array,
1688 * sorts the array, and then iterates over the list setting each element from
1689 * the array.
1690 *
1691 * @param l the List to sort
1692 * @param c the Comparator specifying the ordering for the elements, or
1693 * null for natural ordering
1694 * @throws ClassCastException if c will not compare some pair of items
1695 * @throws UnsupportedOperationException if the List is not modifiable
1696 * @throws NullPointerException if null is compared by natural ordering
1697 * (only possible when c is null)
1698 * @see Arrays#sort(Object[], Comparator)
1699 */
1700 public static void sort(List l, Comparator c)
1701 {
1702 Object[] a = l.toArray();
1703 Arrays.sort(a, c);
1704 ListIterator i = l.listIterator(a.length);
1705 for (int pos = a.length; --pos >= 0; )
1706 {
1707 i.previous();
1708 i.set(a[pos]);
1709 }
1710 }
1711
1712 /**
1713 * Swaps the elements at the specified positions within the list. Equal
1714 * positions have no effect.
1715 *
1716 * @param l the list to work on
1717 * @param i the first index to swap
1718 * @param j the second index
1719 * @throws UnsupportedOperationException if list.set is not supported
1720 * @throws IndexOutOfBoundsException if either i or j is &lt; 0 or &gt;=
1721 * list.size()
1722 * @since 1.4
1723 */
1724 public static void swap(List l, int i, int j)
1725 {
1726 l.set(i, l.set(j, l.get(i)));
1727 }
1728
1729
1730
1731 /**
1732 * Returns a synchronized (thread-safe) collection wrapper backed by the
1733 * given collection. Notice that element access through the iterators
1734 * is thread-safe, but if the collection can be structurally modified
1735 * (adding or removing elements) then you should synchronize around the
1736 * iteration to avoid non-deterministic behavior:<br>
1737 * <pre>
1738 * Collection c = Collections.synchronizedCollection(new Collection(...));
1739 * ...
1740 * synchronized (c)
1741 * {
1742 * Iterator i = c.iterator();
1743 * while (i.hasNext())
1744 * foo(i.next());
1745 * }
1746 * </pre><p>
1747 *
1748 * Since the collection might be a List or a Set, and those have incompatible
1749 * equals and hashCode requirements, this relies on Object's implementation
1750 * rather than passing those calls on to the wrapped collection. The returned
1751 * Collection implements Serializable, but can only be serialized if
1752 * the collection it wraps is likewise Serializable.
1753 *
1754 * @param c the collection to wrap
1755 * @return a synchronized view of the collection
1756 * @see Serializable
1757 */
1758 public static Collection synchronizedCollection(Collection c)
1759 {
1760 return new SynchronizedCollection(c);
1761 }
1762
1763 /**
1764 * The implementation of {@link #synchronizedCollection(Collection)}. This
1765 * class name is required for compatibility with Sun's JDK serializability.
1766 * Package visible, so that collections such as the one for
1767 * Hashtable.values() can specify which object to synchronize on.
1768 *
1769 * @author Eric Blake <ebb9@email.byu.edu>
1770 */
1771 static class SynchronizedCollection
1772 implements Collection, Serializable
1773 {
1774 /**
1775 * Compatible with JDK 1.4.
1776 */
1777 private static final long serialVersionUID = 3053995032091335093L;
1778
1779 /**
1780 * The wrapped collection. Package visible for use by subclasses.
1781 * @serial the real collection
1782 */
1783 final Collection c;
1784
1785 /**
1786 * The object to synchronize on. When an instance is created via public
1787 * methods, it will be this; but other uses like SynchronizedMap.values()
1788 * must specify another mutex. Package visible for use by subclasses.
1789 * @serial the lock
1790 */
1791 final Object mutex;
1792
1793 /**
1794 * Wrap a given collection.
1795 * @param c the collection to wrap
1796 * @throws NullPointerException if c is null
1797 */
1798 SynchronizedCollection(Collection c)
1799 {
1800 this.c = c;
1801 mutex = this;
1802 if (c == null)
1803 throw new NullPointerException();
1804 }
1805
1806 /**
1807 * Called only by trusted code to specify the mutex as well as the
1808 * collection.
1809 * @param sync the mutex
1810 * @param c the collection
1811 */
1812 SynchronizedCollection(Object sync, Collection c)
1813 {
1814 this.c = c;
1815 mutex = sync;
1816 }
1817
1818 public boolean add(Object o)
1819 {
1820 synchronized (mutex)
1821 {
1822 return c.add(o);
1823 }
1824 }
1825
1826 public boolean addAll(Collection col)
1827 {
1828 synchronized (mutex)
1829 {
1830 return c.addAll(col);
1831 }
1832 }
1833
1834 public void clear()
1835 {
1836 synchronized (mutex)
1837 {
1838 c.clear();
1839 }
1840 }
1841
1842 public boolean contains(Object o)
1843 {
1844 synchronized (mutex)
1845 {
1846 return c.contains(o);
1847 }
1848 }
1849
1850 public boolean containsAll(Collection c1)
1851 {
1852 synchronized (mutex)
1853 {
1854 return c.containsAll(c1);
1855 }
1856 }
1857
1858 public boolean isEmpty()
1859 {
1860 synchronized (mutex)
1861 {
1862 return c.isEmpty();
1863 }
1864 }
1865
1866 public Iterator iterator()
1867 {
1868 synchronized (mutex)
1869 {
1870 return new SynchronizedIterator(mutex, c.iterator());
1871 }
1872 }
1873
1874 public boolean remove(Object o)
1875 {
1876 synchronized (mutex)
1877 {
1878 return c.remove(o);
1879 }
1880 }
1881
1882 public boolean removeAll(Collection col)
1883 {
1884 synchronized (mutex)
1885 {
1886 return c.removeAll(col);
1887 }
1888 }
1889
1890 public boolean retainAll(Collection col)
1891 {
1892 synchronized (mutex)
1893 {
1894 return c.retainAll(col);
1895 }
1896 }
1897
1898 public int size()
1899 {
1900 synchronized (mutex)
1901 {
1902 return c.size();
1903 }
1904 }
1905
1906 public Object[] toArray()
1907 {
1908 synchronized (mutex)
1909 {
1910 return c.toArray();
1911 }
1912 }
1913
1914 public Object[] toArray(Object[] a)
1915 {
1916 synchronized (mutex)
1917 {
1918 return c.toArray(a);
1919 }
1920 }
1921
1922 public String toString()
1923 {
1924 synchronized (mutex)
1925 {
1926 return c.toString();
1927 }
1928 }
1929 } // class SynchronizedCollection
1930
1931 /**
1932 * The implementation of the various iterator methods in the
1933 * synchronized classes. These iterators must "sync" on the same object
1934 * as the collection they iterate over.
1935 *
1936 * @author Eric Blake <ebb9@email.byu.edu>
1937 */
1938 private static class SynchronizedIterator implements Iterator
1939 {
1940 /**
1941 * The object to synchronize on. Package visible for use by subclass.
1942 */
1943 final Object mutex;
1944
1945 /**
1946 * The wrapped iterator.
1947 */
1948 private final Iterator i;
1949
1950 /**
1951 * Only trusted code creates a wrapper, with the specified sync.
1952 * @param sync the mutex
1953 * @param i the wrapped iterator
1954 */
1955 SynchronizedIterator(Object sync, Iterator i)
1956 {
1957 this.i = i;
1958 mutex = sync;
1959 }
1960
1961 public Object next()
1962 {
1963 synchronized (mutex)
1964 {
1965 return i.next();
1966 }
1967 }
1968
1969 public boolean hasNext()
1970 {
1971 synchronized (mutex)
1972 {
1973 return i.hasNext();
1974 }
1975 }
1976
1977 public void remove()
1978 {
1979 synchronized (mutex)
1980 {
1981 i.remove();
1982 }
1983 }
1984 } // class SynchronizedIterator
1985
1986 /**
1987 * Returns a synchronized (thread-safe) list wrapper backed by the
1988 * given list. Notice that element access through the iterators
1989 * is thread-safe, but if the list can be structurally modified
1990 * (adding or removing elements) then you should synchronize around the
1991 * iteration to avoid non-deterministic behavior:<br>
1992 * <pre>
1993 * List l = Collections.synchronizedList(new List(...));
1994 * ...
1995 * synchronized (l)
1996 * {
1997 * Iterator i = l.iterator();
1998 * while (i.hasNext())
1999 * foo(i.next());
2000 * }
2001 * </pre><p>
2002 *
2003 * The returned List implements Serializable, but can only be serialized if
2004 * the list it wraps is likewise Serializable. In addition, if the wrapped
2005 * list implements RandomAccess, this does too.
2006 *
2007 * @param l the list to wrap
2008 * @return a synchronized view of the list
2009 * @see Serializable
2010 * @see RandomAccess
2011 */
2012 public static List synchronizedList(List l)
2013 {
2014 if (l instanceof RandomAccess)
2015 return new SynchronizedRandomAccessList(l);
2016 return new SynchronizedList(l);
2017 }
2018
2019 /**
2020 * The implementation of {@link #synchronizedList(List)} for sequential
2021 * lists. This class name is required for compatibility with Sun's JDK
2022 * serializability. Package visible, so that lists such as Vector.subList()
2023 * can specify which object to synchronize on.
2024 *
2025 * @author Eric Blake <ebb9@email.byu.edu>
2026 */
2027 static class SynchronizedList extends SynchronizedCollection
2028 implements List
2029 {
2030 /**
2031 * Compatible with JDK 1.4.
2032 */
2033 private static final long serialVersionUID = -7754090372962971524L;
2034
2035 /**
2036 * The wrapped list; stored both here and in the superclass to avoid
2037 * excessive casting. Package visible for use by subclass.
2038 * @serial the wrapped list
2039 */
2040 final List list;
2041
2042 /**
2043 * Wrap a given list.
2044 * @param l the list to wrap
2045 * @throws NullPointerException if l is null
2046 */
2047 SynchronizedList(List l)
2048 {
2049 super(l);
2050 list = l;
2051 }
2052
2053 /**
2054 * Called only by trusted code to specify the mutex as well as the list.
2055 * @param sync the mutex
2056 * @param l the list
2057 */
2058 SynchronizedList(Object sync, List l)
2059 {
2060 super(sync, l);
2061 list = l;
2062 }
2063
2064 public void add(int index, Object o)
2065 {
2066 synchronized (mutex)
2067 {
2068 list.add(index, o);
2069 }
2070 }
2071
2072 public boolean addAll(int index, Collection c)
2073 {
2074 synchronized (mutex)
2075 {
2076 return list.addAll(index, c);
2077 }
2078 }
2079
2080 public boolean equals(Object o)
2081 {
2082 synchronized (mutex)
2083 {
2084 return list.equals(o);
2085 }
2086 }
2087
2088 public Object get(int index)
2089 {
2090 synchronized (mutex)
2091 {
2092 return list.get(index);
2093 }
2094 }
2095
2096 public int hashCode()
2097 {
2098 synchronized (mutex)
2099 {
2100 return list.hashCode();
2101 }
2102 }
2103
2104 public int indexOf(Object o)
2105 {
2106 synchronized (mutex)
2107 {
2108 return list.indexOf(o);
2109 }
2110 }
2111
2112 public int lastIndexOf(Object o)
2113 {
2114 synchronized (mutex)
2115 {
2116 return list.lastIndexOf(o);
2117 }
2118 }
2119
2120 public ListIterator listIterator()
2121 {
2122 synchronized (mutex)
2123 {
2124 return new SynchronizedListIterator(mutex, list.listIterator());
2125 }
2126 }
2127
2128 public ListIterator listIterator(int index)
2129 {
2130 synchronized (mutex)
2131 {
2132 return new SynchronizedListIterator(mutex, list.listIterator(index));
2133 }
2134 }
2135
2136 public Object remove(int index)
2137 {
2138 synchronized (mutex)
2139 {
2140 return list.remove(index);
2141 }
2142 }
2143
2144 public Object set(int index, Object o)
2145 {
2146 synchronized (mutex)
2147 {
2148 return list.set(index, o);
2149 }
2150 }
2151
2152 public List subList(int fromIndex, int toIndex)
2153 {
2154 synchronized (mutex)
2155 {
2156 return new SynchronizedList(mutex, list.subList(fromIndex, toIndex));
2157 }
2158 }
2159 } // class SynchronizedList
2160
2161 /**
2162 * The implementation of {@link #synchronizedList(List)} for random-access
2163 * lists. This class name is required for compatibility with Sun's JDK
2164 * serializability.
2165 *
2166 * @author Eric Blake <ebb9@email.byu.edu>
2167 */
2168 private static final class SynchronizedRandomAccessList
2169 extends SynchronizedList implements RandomAccess
2170 {
2171 /**
2172 * Compatible with JDK 1.4.
2173 */
2174 private static final long serialVersionUID = 1530674583602358482L;
2175
2176 /**
2177 * Wrap a given list.
2178 * @param l the list to wrap
2179 * @throws NullPointerException if l is null
2180 */
2181 SynchronizedRandomAccessList(List l)
2182 {
2183 super(l);
2184 }
2185
2186 /**
2187 * Called only by trusted code to specify the mutex as well as the
2188 * collection.
2189 * @param sync the mutex
2190 * @param l the list
2191 */
2192 SynchronizedRandomAccessList(Object sync, List l)
2193 {
2194 super(sync, l);
2195 }
2196
2197 public List subList(int fromIndex, int toIndex)
2198 {
2199 synchronized (mutex)
2200 {
2201 return new SynchronizedRandomAccessList(mutex,
2202 list.subList(fromIndex,
2203 toIndex));
2204 }
2205 }
2206 } // class SynchronizedRandomAccessList
2207
2208 /**
2209 * The implementation of {@link SynchronizedList#listIterator()}. This
2210 * iterator must "sync" on the same object as the list it iterates over.
2211 *
2212 * @author Eric Blake <ebb9@email.byu.edu>
2213 */
2214 private static final class SynchronizedListIterator
2215 extends SynchronizedIterator implements ListIterator
2216 {
2217 /**
2218 * The wrapped iterator, stored both here and in the superclass to
2219 * avoid excessive casting.
2220 */
2221 private final ListIterator li;
2222
2223 /**
2224 * Only trusted code creates a wrapper, with the specified sync.
2225 * @param sync the mutex
2226 * @param li the wrapped iterator
2227 */
2228 SynchronizedListIterator(Object sync, ListIterator li)
2229 {
2230 super(sync, li);
2231 this.li = li;
2232 }
2233
2234 public void add(Object o)
2235 {
2236 synchronized (mutex)
2237 {
2238 li.add(o);
2239 }
2240 }
2241 public boolean hasPrevious()
2242 {
2243 synchronized (mutex)
2244 {
2245 return li.hasPrevious();
2246 }
2247 }
2248
2249 public int nextIndex()
2250 {
2251 synchronized (mutex)
2252 {
2253 return li.nextIndex();
2254 }
2255 }
2256
2257 public Object previous()
2258 {
2259 synchronized (mutex)
2260 {
2261 return li.previous();
2262 }
2263 }
2264
2265 public int previousIndex()
2266 {
2267 synchronized (mutex)
2268 {
2269 return li.previousIndex();
2270 }
2271 }
2272
2273 public void set(Object o)
2274 {
2275 synchronized (mutex)
2276 {
2277 li.set(o);
2278 }
2279 }
2280 } // class SynchronizedListIterator
2281
2282 /**
2283 * Returns a synchronized (thread-safe) map wrapper backed by the given
2284 * map. Notice that element access through the collection views and their
2285 * iterators are thread-safe, but if the map can be structurally modified
2286 * (adding or removing elements) then you should synchronize around the
2287 * iteration to avoid non-deterministic behavior:<br>
2288 * <pre>
2289 * Map m = Collections.synchronizedMap(new Map(...));
2290 * ...
2291 * Set s = m.keySet(); // safe outside a synchronized block
2292 * synchronized (m) // synch on m, not s
2293 * {
2294 * Iterator i = s.iterator();
2295 * while (i.hasNext())
2296 * foo(i.next());
2297 * }
2298 * </pre><p>
2299 *
2300 * The returned Map implements Serializable, but can only be serialized if
2301 * the map it wraps is likewise Serializable.
2302 *
2303 * @param m the map to wrap
2304 * @return a synchronized view of the map
2305 * @see Serializable
2306 */
2307 public static Map synchronizedMap(Map m)
2308 {
2309 return new SynchronizedMap(m);
2310 }
2311
2312 /**
2313 * The implementation of {@link #synchronizedMap(Map)}. This
2314 * class name is required for compatibility with Sun's JDK serializability.
2315 *
2316 * @author Eric Blake <ebb9@email.byu.edu>
2317 */
2318 private static class SynchronizedMap implements Map, Serializable
2319 {
2320 /**
2321 * Compatible with JDK 1.4.
2322 */
2323 private static final long serialVersionUID = 1978198479659022715L;
2324
2325 /**
2326 * The wrapped map.
2327 * @serial the real map
2328 */
2329 private final Map m;
2330
2331 /**
2332 * The object to synchronize on. When an instance is created via public
2333 * methods, it will be this; but other uses like
2334 * SynchronizedSortedMap.subMap() must specify another mutex. Package
2335 * visible for use by subclass.
2336 * @serial the lock
2337 */
2338 final Object mutex;
2339
2340 /**
2341 * Cache the entry set.
2342 */
2343 private transient Set entries;
2344
2345 /**
2346 * Cache the key set.
2347 */
2348 private transient Set keys;
2349
2350 /**
2351 * Cache the value collection.
2352 */
2353 private transient Collection values;
2354
2355 /**
2356 * Wrap a given map.
2357 * @param m the map to wrap
2358 * @throws NullPointerException if m is null
2359 */
2360 SynchronizedMap(Map m)
2361 {
2362 this.m = m;
2363 mutex = this;
2364 if (m == null)
2365 throw new NullPointerException();
2366 }
2367
2368 /**
2369 * Called only by trusted code to specify the mutex as well as the map.
2370 * @param sync the mutex
2371 * @param m the map
2372 */
2373 SynchronizedMap(Object sync, Map m)
2374 {
2375 this.m = m;
2376 mutex = sync;
2377 }
2378
2379 public void clear()
2380 {
2381 synchronized (mutex)
2382 {
2383 m.clear();
2384 }
2385 }
2386
2387 public boolean containsKey(Object key)
2388 {
2389 synchronized (mutex)
2390 {
2391 return m.containsKey(key);
2392 }
2393 }
2394
2395 public boolean containsValue(Object value)
2396 {
2397 synchronized (mutex)
2398 {
2399 return m.containsValue(value);
2400 }
2401 }
2402
2403 // This is one of the ickiest cases of nesting I've ever seen. It just
2404 // means "return a SynchronizedSet, except that the iterator() method
2405 // returns an SynchronizedIterator whose next() method returns a
2406 // synchronized wrapper around its normal return value".
2407 public Set entrySet()
2408 {
2409 // Define this here to spare some nesting.
2410 class SynchronizedMapEntry implements Map.Entry
2411 {
2412 final Map.Entry e;
2413 SynchronizedMapEntry(Object o)
2414 {
2415 e = (Map.Entry) o;
2416 }
2417 public boolean equals(Object o)
2418 {
2419 synchronized (mutex)
2420 {
2421 return e.equals(o);
2422 }
2423 }
2424 public Object getKey()
2425 {
2426 synchronized (mutex)
2427 {
2428 return e.getKey();
2429 }
2430 }
2431 public Object getValue()
2432 {
2433 synchronized (mutex)
2434 {
2435 return e.getValue();
2436 }
2437 }
2438 public int hashCode()
2439 {
2440 synchronized (mutex)
2441 {
2442 return e.hashCode();
2443 }
2444 }
2445 public Object setValue(Object value)
2446 {
2447 synchronized (mutex)
2448 {
2449 return e.setValue(value);
2450 }
2451 }
2452 public String toString()
2453 {
2454 synchronized (mutex)
2455 {
2456 return e.toString();
2457 }
2458 }
2459 } // class SynchronizedMapEntry
2460
2461 // Now the actual code.
2462 if (entries == null)
2463 synchronized (mutex)
2464 {
2465 entries = new SynchronizedSet(mutex, m.entrySet())
2466 {
2467 public Iterator iterator()
2468 {
2469 synchronized (super.mutex)
2470 {
2471 return new SynchronizedIterator(super.mutex, c.iterator())
2472 {
2473 public Object next()
2474 {
2475 synchronized (super.mutex)
2476 {
2477 return new SynchronizedMapEntry(super.next());
2478 }
2479 }
2480 };
2481 }
2482 }
2483 };
2484 }
2485 return entries;
2486 }
2487
2488 public boolean equals(Object o)
2489 {
2490 synchronized (mutex)
2491 {
2492 return m.equals(o);
2493 }
2494 }
2495
2496 public Object get(Object key)
2497 {
2498 synchronized (mutex)
2499 {
2500 return m.get(key);
2501 }
2502 }
2503
2504 public int hashCode()
2505 {
2506 synchronized (mutex)
2507 {
2508 return m.hashCode();
2509 }
2510 }
2511
2512 public boolean isEmpty()
2513 {
2514 synchronized (mutex)
2515 {
2516 return m.isEmpty();
2517 }
2518 }
2519
2520 public Set keySet()
2521 {
2522 if (keys == null)
2523 synchronized (mutex)
2524 {
2525 keys = new SynchronizedSet(mutex, m.keySet());
2526 }
2527 return keys;
2528 }
2529
2530 public Object put(Object key, Object value)
2531 {
2532 synchronized (mutex)
2533 {
2534 return m.put(key, value);
2535 }
2536 }
2537
2538 public void putAll(Map map)
2539 {
2540 synchronized (mutex)
2541 {
2542 m.putAll(map);
2543 }
2544 }
2545
2546 public Object remove(Object o)
2547 {
2548 synchronized (mutex)
2549 {
2550 return m.remove(o);
2551 }
2552 }
2553
2554 public int size()
2555 {
2556 synchronized (mutex)
2557 {
2558 return m.size();
2559 }
2560 }
2561
2562 public String toString()
2563 {
2564 synchronized (mutex)
2565 {
2566 return m.toString();
2567 }
2568 }
2569
2570 public Collection values()
2571 {
2572 if (values == null)
2573 synchronized (mutex)
2574 {
2575 values = new SynchronizedCollection(mutex, m.values());
2576 }
2577 return values;
2578 }
2579 } // class SynchronizedMap
2580
2581 /**
2582 * Returns a synchronized (thread-safe) set wrapper backed by the given
2583 * set. Notice that element access through the iterator is thread-safe, but
2584 * if the set can be structurally modified (adding or removing elements)
2585 * then you should synchronize around the iteration to avoid
2586 * non-deterministic behavior:<br>
2587 * <pre>
2588 * Set s = Collections.synchronizedSet(new Set(...));
2589 * ...
2590 * synchronized (s)
2591 * {
2592 * Iterator i = s.iterator();
2593 * while (i.hasNext())
2594 * foo(i.next());
2595 * }
2596 * </pre><p>
2597 *
2598 * The returned Set implements Serializable, but can only be serialized if
2599 * the set it wraps is likewise Serializable.
2600 *
2601 * @param s the set to wrap
2602 * @return a synchronized view of the set
2603 * @see Serializable
2604 */
2605 public static Set synchronizedSet(Set s)
2606 {
2607 return new SynchronizedSet(s);
2608 }
2609
2610 /**
2611 * The implementation of {@link #synchronizedSet(Set)}. This class
2612 * name is required for compatibility with Sun's JDK serializability.
2613 * Package visible, so that sets such as Hashtable.keySet()
2614 * can specify which object to synchronize on.
2615 *
2616 * @author Eric Blake <ebb9@email.byu.edu>
2617 */
2618 static class SynchronizedSet extends SynchronizedCollection
2619 implements Set
2620 {
2621 /**
2622 * Compatible with JDK 1.4.
2623 */
2624 private static final long serialVersionUID = 487447009682186044L;
2625
2626 /**
2627 * Wrap a given set.
2628 * @param s the set to wrap
2629 * @throws NullPointerException if s is null
2630 */
2631 SynchronizedSet(Set s)
2632 {
2633 super(s);
2634 }
2635
2636 /**
2637 * Called only by trusted code to specify the mutex as well as the set.
2638 * @param sync the mutex
2639 * @param s the set
2640 */
2641 SynchronizedSet(Object sync, Set s)
2642 {
2643 super(sync, s);
2644 }
2645
2646 public boolean equals(Object o)
2647 {
2648 synchronized (mutex)
2649 {
2650 return c.equals(o);
2651 }
2652 }
2653
2654 public int hashCode()
2655 {
2656 synchronized (mutex)
2657 {
2658 return c.hashCode();
2659 }
2660 }
2661 } // class SynchronizedSet
2662
2663 /**
2664 * Returns a synchronized (thread-safe) sorted map wrapper backed by the
2665 * given map. Notice that element access through the collection views,
2666 * subviews, and their iterators are thread-safe, but if the map can be
2667 * structurally modified (adding or removing elements) then you should
2668 * synchronize around the iteration to avoid non-deterministic behavior:<br>
2669 * <pre>
2670 * SortedMap m = Collections.synchronizedSortedMap(new SortedMap(...));
2671 * ...
2672 * Set s = m.keySet(); // safe outside a synchronized block
2673 * SortedMap m2 = m.headMap(foo); // safe outside a synchronized block
2674 * Set s2 = m2.keySet(); // safe outside a synchronized block
2675 * synchronized (m) // synch on m, not m2, s or s2
2676 * {
2677 * Iterator i = s.iterator();
2678 * while (i.hasNext())
2679 * foo(i.next());
2680 * i = s2.iterator();
2681 * while (i.hasNext())
2682 * bar(i.next());
2683 * }
2684 * </pre><p>
2685 *
2686 * The returned SortedMap implements Serializable, but can only be
2687 * serialized if the map it wraps is likewise Serializable.
2688 *
2689 * @param m the sorted map to wrap
2690 * @return a synchronized view of the sorted map
2691 * @see Serializable
2692 */
2693 public static SortedMap synchronizedSortedMap(SortedMap m)
2694 {
2695 return new SynchronizedSortedMap(m);
2696 }
2697
2698 /**
2699 * The implementation of {@link #synchronizedSortedMap(SortedMap)}. This
2700 * class name is required for compatibility with Sun's JDK serializability.
2701 *
2702 * @author Eric Blake <ebb9@email.byu.edu>
2703 */
2704 private static final class SynchronizedSortedMap extends SynchronizedMap
2705 implements SortedMap
2706 {
2707 /**
2708 * Compatible with JDK 1.4.
2709 */
2710 private static final long serialVersionUID = -8798146769416483793L;
2711
2712 /**
2713 * The wrapped map; stored both here and in the superclass to avoid
2714 * excessive casting.
2715 * @serial the wrapped map
2716 */
2717 private final SortedMap sm;
2718
2719 /**
2720 * Wrap a given map.
2721 * @param sm the map to wrap
2722 * @throws NullPointerException if sm is null
2723 */
2724 SynchronizedSortedMap(SortedMap sm)
2725 {
2726 super(sm);
2727 this.sm = sm;
2728 }
2729
2730 /**
2731 * Called only by trusted code to specify the mutex as well as the map.
2732 * @param sync the mutex
2733 * @param sm the map
2734 */
2735 SynchronizedSortedMap(Object sync, SortedMap sm)
2736 {
2737 super(sync, sm);
2738 this.sm = sm;
2739 }
2740
2741 public Comparator comparator()
2742 {
2743 synchronized (mutex)
2744 {
2745 return sm.comparator();
2746 }
2747 }
2748
2749 public Object firstKey()
2750 {
2751 synchronized (mutex)
2752 {
2753 return sm.firstKey();
2754 }
2755 }
2756
2757 public SortedMap headMap(Object toKey)
2758 {
2759 synchronized (mutex)
2760 {
2761 return new SynchronizedSortedMap(mutex, sm.headMap(toKey));
2762 }
2763 }
2764
2765 public Object lastKey()
2766 {
2767 synchronized (mutex)
2768 {
2769 return sm.lastKey();
2770 }
2771 }
2772
2773 public SortedMap subMap(Object fromKey, Object toKey)
2774 {
2775 synchronized (mutex)
2776 {
2777 return new SynchronizedSortedMap(mutex, sm.subMap(fromKey, toKey));
2778 }
2779 }
2780
2781 public SortedMap tailMap(Object fromKey)
2782 {
2783 synchronized (mutex)
2784 {
2785 return new SynchronizedSortedMap(mutex, sm.tailMap(fromKey));
2786 }
2787 }
2788 } // class SynchronizedSortedMap
2789
2790 /**
2791 * Returns a synchronized (thread-safe) sorted set wrapper backed by the
2792 * given set. Notice that element access through the iterator and through
2793 * subviews are thread-safe, but if the set can be structurally modified
2794 * (adding or removing elements) then you should synchronize around the
2795 * iteration to avoid non-deterministic behavior:<br>
2796 * <pre>
2797 * SortedSet s = Collections.synchronizedSortedSet(new SortedSet(...));
2798 * ...
2799 * SortedSet s2 = s.headSet(foo); // safe outside a synchronized block
2800 * synchronized (s) // synch on s, not s2
2801 * {
2802 * Iterator i = s2.iterator();
2803 * while (i.hasNext())
2804 * foo(i.next());
2805 * }
2806 * </pre><p>
2807 *
2808 * The returned SortedSet implements Serializable, but can only be
2809 * serialized if the set it wraps is likewise Serializable.
2810 *
2811 * @param s the sorted set to wrap
2812 * @return a synchronized view of the sorted set
2813 * @see Serializable
2814 */
2815 public static SortedSet synchronizedSortedSet(SortedSet s)
2816 {
2817 return new SynchronizedSortedSet(s);
2818 }
2819
2820 /**
2821 * The implementation of {@link #synchronizedSortedSet(SortedSet)}. This
2822 * class name is required for compatibility with Sun's JDK serializability.
2823 *
2824 * @author Eric Blake <ebb9@email.byu.edu>
2825 */
2826 private static final class SynchronizedSortedSet extends SynchronizedSet
2827 implements SortedSet
2828 {
2829 /**
2830 * Compatible with JDK 1.4.
2831 */
2832 private static final long serialVersionUID = 8695801310862127406L;
2833
2834 /**
2835 * The wrapped set; stored both here and in the superclass to avoid
2836 * excessive casting.
2837 * @serial the wrapped set
2838 */
2839 private final SortedSet ss;
2840
2841 /**
2842 * Wrap a given set.
2843 * @param ss the set to wrap
2844 * @throws NullPointerException if ss is null
2845 */
2846 SynchronizedSortedSet(SortedSet ss)
2847 {
2848 super(ss);
2849 this.ss = ss;
2850 }
2851
2852 /**
2853 * Called only by trusted code to specify the mutex as well as the set.
2854 * @param sync the mutex
2855 * @param l the list
2856 */
2857 SynchronizedSortedSet(Object sync, SortedSet ss)
2858 {
2859 super(sync, ss);
2860 this.ss = ss;
2861 }
2862
2863 public Comparator comparator()
2864 {
2865 synchronized (mutex)
2866 {
2867 return ss.comparator();
2868 }
2869 }
2870
2871 public Object first()
2872 {
2873 synchronized (mutex)
2874 {
2875 return ss.first();
2876 }
2877 }
2878
2879 public SortedSet headSet(Object toElement)
2880 {
2881 synchronized (mutex)
2882 {
2883 return new SynchronizedSortedSet(mutex, ss.headSet(toElement));
2884 }
2885 }
2886
2887 public Object last()
2888 {
2889 synchronized (mutex)
2890 {
2891 return ss.last();
2892 }
2893 }
2894
2895 public SortedSet subSet(Object fromElement, Object toElement)
2896 {
2897 synchronized (mutex)
2898 {
2899 return new SynchronizedSortedSet(mutex,
2900 ss.subSet(fromElement, toElement));
2901 }
2902 }
2903
2904 public SortedSet tailSet(Object fromElement)
2905 {
2906 synchronized (mutex)
2907 {
2908 return new SynchronizedSortedSet(mutex, ss.tailSet(fromElement));
2909 }
2910 }
2911 } // class SynchronizedSortedSet
2912
2913
2914
2915 /**
2916 * Returns an unmodifiable view of the given collection. This allows
2917 * "read-only" access, although changes in the backing collection show up
2918 * in this view. Attempts to modify the collection directly or via iterators
2919 * will fail with {@link UnsupportedOperationException}.
2920 * <p>
2921 *
2922 * Since the collection might be a List or a Set, and those have incompatible
2923 * equals and hashCode requirements, this relies on Object's implementation
2924 * rather than passing those calls on to the wrapped collection. The returned
2925 * Collection implements Serializable, but can only be serialized if
2926 * the collection it wraps is likewise Serializable.
2927 *
2928 * @param c the collection to wrap
2929 * @return a read-only view of the collection
2930 * @see Serializable
2931 */
2932 public static Collection unmodifiableCollection(Collection c)
2933 {
2934 return new UnmodifiableCollection(c);
2935 }
2936
2937 /**
2938 * The implementation of {@link #unmodifiableCollection(Collection)}. This
2939 * class name is required for compatibility with Sun's JDK serializability.
2940 *
2941 * @author Eric Blake <ebb9@email.byu.edu>
2942 */
2943 private static class UnmodifiableCollection
2944 implements Collection, Serializable
2945 {
2946 /**
2947 * Compatible with JDK 1.4.
2948 */
2949 private static final long serialVersionUID = 1820017752578914078L;
2950
2951 /**
2952 * The wrapped collection. Package visible for use by subclasses.
2953 * @serial the real collection
2954 */
2955 final Collection c;
2956
2957 /**
2958 * Wrap a given collection.
2959 * @param c the collection to wrap
2960 * @throws NullPointerException if c is null
2961 */
2962 UnmodifiableCollection(Collection c)
2963 {
2964 this.c = c;
2965 if (c == null)
2966 throw new NullPointerException();
2967 }
2968
2969 public boolean add(Object o)
2970 {
2971 throw new UnsupportedOperationException();
2972 }
2973
2974 public boolean addAll(Collection c)
2975 {
2976 throw new UnsupportedOperationException();
2977 }
2978
2979 public void clear()
2980 {
2981 throw new UnsupportedOperationException();
2982 }
2983
2984 public boolean contains(Object o)
2985 {
2986 return c.contains(o);
2987 }
2988
2989 public boolean containsAll(Collection c1)
2990 {
2991 return c.containsAll(c1);
2992 }
2993
2994 public boolean isEmpty()
2995 {
2996 return c.isEmpty();
2997 }
2998
2999 public Iterator iterator()
3000 {
3001 return new UnmodifiableIterator(c.iterator());
3002 }
3003
3004 public boolean remove(Object o)
3005 {
3006 throw new UnsupportedOperationException();
3007 }
3008
3009 public boolean removeAll(Collection c)
3010 {
3011 throw new UnsupportedOperationException();
3012 }
3013
3014 public boolean retainAll(Collection c)
3015 {
3016 throw new UnsupportedOperationException();
3017 }
3018
3019 public int size()
3020 {
3021 return c.size();
3022 }
3023
3024 public Object[] toArray()
3025 {
3026 return c.toArray();
3027 }
3028
3029 public Object[] toArray(Object[] a)
3030 {
3031 return c.toArray(a);
3032 }
3033
3034 public String toString()
3035 {
3036 return c.toString();
3037 }
3038 } // class UnmodifiableCollection
3039
3040 /**
3041 * The implementation of the various iterator methods in the
3042 * unmodifiable classes.
3043 *
3044 * @author Eric Blake <ebb9@email.byu.edu>
3045 */
3046 private static class UnmodifiableIterator implements Iterator
3047 {
3048 /**
3049 * The wrapped iterator.
3050 */
3051 private final Iterator i;
3052
3053 /**
3054 * Only trusted code creates a wrapper.
3055 * @param i the wrapped iterator
3056 */
3057 UnmodifiableIterator(Iterator i)
3058 {
3059 this.i = i;
3060 }
3061
3062 public Object next()
3063 {
3064 return i.next();
3065 }
3066
3067 public boolean hasNext()
3068 {
3069 return i.hasNext();
3070 }
3071
3072 public void remove()
3073 {
3074 throw new UnsupportedOperationException();
3075 }
3076 } // class UnmodifiableIterator
3077
3078 /**
3079 * Returns an unmodifiable view of the given list. This allows
3080 * "read-only" access, although changes in the backing list show up
3081 * in this view. Attempts to modify the list directly, via iterators, or
3082 * via sublists, will fail with {@link UnsupportedOperationException}.
3083 * <p>
3084 *
3085 * The returned List implements Serializable, but can only be serialized if
3086 * the list it wraps is likewise Serializable. In addition, if the wrapped
3087 * list implements RandomAccess, this does too.
3088 *
3089 * @param l the list to wrap
3090 * @return a read-only view of the list
3091 * @see Serializable
3092 * @see RandomAccess
3093 */
3094 public static List unmodifiableList(List l)
3095 {
3096 if (l instanceof RandomAccess)
3097 return new UnmodifiableRandomAccessList(l);
3098 return new UnmodifiableList(l);
3099 }
3100
3101 /**
3102 * The implementation of {@link #unmodifiableList(List)} for sequential
3103 * lists. This class name is required for compatibility with Sun's JDK
3104 * serializability.
3105 *
3106 * @author Eric Blake <ebb9@email.byu.edu>
3107 */
3108 private static class UnmodifiableList extends UnmodifiableCollection
3109 implements List
3110 {
3111 /**
3112 * Compatible with JDK 1.4.
3113 */
3114 private static final long serialVersionUID = -283967356065247728L;
3115
3116
3117 /**
3118 * The wrapped list; stored both here and in the superclass to avoid
3119 * excessive casting. Package visible for use by subclass.
3120 * @serial the wrapped list
3121 */
3122 final List list;
3123
3124 /**
3125 * Wrap a given list.
3126 * @param l the list to wrap
3127 * @throws NullPointerException if l is null
3128 */
3129 UnmodifiableList(List l)
3130 {
3131 super(l);
3132 list = l;
3133 }
3134
3135 public void add(int index, Object o)
3136 {
3137 throw new UnsupportedOperationException();
3138 }
3139
3140 public boolean addAll(int index, Collection c)
3141 {
3142 throw new UnsupportedOperationException();
3143 }
3144
3145 public boolean equals(Object o)
3146 {
3147 return list.equals(o);
3148 }
3149
3150 public Object get(int index)
3151 {
3152 return list.get(index);
3153 }
3154
3155 public int hashCode()
3156 {
3157 return list.hashCode();
3158 }
3159
3160 public int indexOf(Object o)
3161 {
3162 return list.indexOf(o);
3163 }
3164
3165 public int lastIndexOf(Object o)
3166 {
3167 return list.lastIndexOf(o);
3168 }
3169
3170 public ListIterator listIterator()
3171 {
3172 return new UnmodifiableListIterator(list.listIterator());
3173 }
3174
3175 public ListIterator listIterator(int index)
3176 {
3177 return new UnmodifiableListIterator(list.listIterator(index));
3178 }
3179
3180 public Object remove(int index)
3181 {
3182 throw new UnsupportedOperationException();
3183 }
3184
3185 public Object set(int index, Object o)
3186 {
3187 throw new UnsupportedOperationException();
3188 }
3189
3190 public List subList(int fromIndex, int toIndex)
3191 {
3192 return unmodifiableList(list.subList(fromIndex, toIndex));
3193 }
3194 } // class UnmodifiableList
3195
3196 /**
3197 * The implementation of {@link #unmodifiableList(List)} for random-access
3198 * lists. This class name is required for compatibility with Sun's JDK
3199 * serializability.
3200 *
3201 * @author Eric Blake <ebb9@email.byu.edu>
3202 */
3203 private static final class UnmodifiableRandomAccessList
3204 extends UnmodifiableList implements RandomAccess
3205 {
3206 /**
3207 * Compatible with JDK 1.4.
3208 */
3209 private static final long serialVersionUID = -2542308836966382001L;
3210
3211 /**
3212 * Wrap a given list.
3213 * @param l the list to wrap
3214 * @throws NullPointerException if l is null
3215 */
3216 UnmodifiableRandomAccessList(List l)
3217 {
3218 super(l);
3219 }
3220 } // class UnmodifiableRandomAccessList
3221
3222 /**
3223 * The implementation of {@link UnmodifiableList#listIterator()}.
3224 *
3225 * @author Eric Blake <ebb9@email.byu.edu>
3226 */
3227 private static final class UnmodifiableListIterator
3228 extends UnmodifiableIterator implements ListIterator
3229 {
3230 /**
3231 * The wrapped iterator, stored both here and in the superclass to
3232 * avoid excessive casting.
3233 */
3234 private final ListIterator li;
3235
3236 /**
3237 * Only trusted code creates a wrapper.
3238 * @param li the wrapped iterator
3239 */
3240 UnmodifiableListIterator(ListIterator li)
3241 {
3242 super(li);
3243 this.li = li;
3244 }
3245
3246 public void add(Object o)
3247 {
3248 throw new UnsupportedOperationException();
3249 }
3250
3251 public boolean hasPrevious()
3252 {
3253 return li.hasPrevious();
3254 }
3255
3256 public int nextIndex()
3257 {
3258 return li.nextIndex();
3259 }
3260
3261 public Object previous()
3262 {
3263 return li.previous();
3264 }
3265
3266 public int previousIndex()
3267 {
3268 return li.previousIndex();
3269 }
3270
3271 public void set(Object o)
3272 {
3273 throw new UnsupportedOperationException();
3274 }
3275 } // class UnmodifiableListIterator
3276
3277 /**
3278 * Returns an unmodifiable view of the given map. This allows "read-only"
3279 * access, although changes in the backing map show up in this view.
3280 * Attempts to modify the map directly, or via collection views or their
3281 * iterators will fail with {@link UnsupportedOperationException}.
3282 * <p>
3283 *
3284 * The returned Map implements Serializable, but can only be serialized if
3285 * the map it wraps is likewise Serializable.
3286 *
3287 * @param m the map to wrap
3288 * @return a read-only view of the map
3289 * @see Serializable
3290 */
3291 public static Map unmodifiableMap(Map m)
3292 {
3293 return new UnmodifiableMap(m);
3294 }
3295
3296 /**
3297 * The implementation of {@link #unmodifiableMap(Map)}. This
3298 * class name is required for compatibility with Sun's JDK serializability.
3299 *
3300 * @author Eric Blake <ebb9@email.byu.edu>
3301 */
3302 private static class UnmodifiableMap implements Map, Serializable
3303 {
3304 /**
3305 * Compatible with JDK 1.4.
3306 */
3307 private static final long serialVersionUID = -1034234728574286014L;
3308
3309 /**
3310 * The wrapped map.
3311 * @serial the real map
3312 */
3313 private final Map m;
3314
3315 /**
3316 * Cache the entry set.
3317 */
3318 private transient Set entries;
3319
3320 /**
3321 * Cache the key set.
3322 */
3323 private transient Set keys;
3324
3325 /**
3326 * Cache the value collection.
3327 */
3328 private transient Collection values;
3329
3330 /**
3331 * Wrap a given map.
3332 * @param m the map to wrap
3333 * @throws NullPointerException if m is null
3334 */
3335 UnmodifiableMap(Map m)
3336 {
3337 this.m = m;
3338 if (m == null)
3339 throw new NullPointerException();
3340 }
3341
3342 public void clear()
3343 {
3344 throw new UnsupportedOperationException();
3345 }
3346
3347 public boolean containsKey(Object key)
3348 {
3349 return m.containsKey(key);
3350 }
3351
3352 public boolean containsValue(Object value)
3353 {
3354 return m.containsValue(value);
3355 }
3356
3357 public Set entrySet()
3358 {
3359 if (entries == null)
3360 entries = new UnmodifiableEntrySet(m.entrySet());
3361 return entries;
3362 }
3363
3364 /**
3365 * The implementation of {@link UnmodifiableMap#entrySet()}. This class
3366 * name is required for compatibility with Sun's JDK serializability.
3367 *
3368 * @author Eric Blake <ebb9@email.byu.edu>
3369 */
3370 private static final class UnmodifiableEntrySet extends UnmodifiableSet
3371 implements Serializable
3372 {
3373 /**
3374 * Compatible with JDK 1.4.
3375 */
3376 private static final long serialVersionUID = 7854390611657943733L;
3377
3378 /**
3379 * Wrap a given set.
3380 * @param s the set to wrap
3381 */
3382 UnmodifiableEntrySet(Set s)
3383 {
3384 super(s);
3385 }
3386
3387 // The iterator must return unmodifiable map entries.
3388 public Iterator iterator()
3389 {
3390 return new UnmodifiableIterator(c.iterator())
3391 {
3392 public Object next()
3393 {
3394 final Map.Entry e = (Map.Entry) super.next();
3395 return new Map.Entry()
3396 {
3397 public boolean equals(Object o)
3398 {
3399 return e.equals(o);
3400 }
3401 public Object getKey()
3402 {
3403 return e.getKey();
3404 }
3405 public Object getValue()
3406 {
3407 return e.getValue();
3408 }
3409 public int hashCode()
3410 {
3411 return e.hashCode();
3412 }
3413 public Object setValue(Object value)
3414 {
3415 throw new UnsupportedOperationException();
3416 }
3417 public String toString()
3418 {
3419 return e.toString();
3420 }
3421 };
3422 }
3423 };
3424 }
3425 } // class UnmodifiableEntrySet
3426
3427 public boolean equals(Object o)
3428 {
3429 return m.equals(o);
3430 }
3431
3432 public Object get(Object key)
3433 {
3434 return m.get(key);
3435 }
3436
3437 public Object put(Object key, Object value)
3438 {
3439 throw new UnsupportedOperationException();
3440 }
3441
3442 public int hashCode()
3443 {
3444 return m.hashCode();
3445 }
3446
3447 public boolean isEmpty()
3448 {
3449 return m.isEmpty();
3450 }
3451
3452 public Set keySet()
3453 {
3454 if (keys == null)
3455 keys = new UnmodifiableSet(m.keySet());
3456 return keys;
3457 }
3458
3459 public void putAll(Map m)
3460 {
3461 throw new UnsupportedOperationException();
3462 }
3463
3464 public Object remove(Object o)
3465 {
3466 throw new UnsupportedOperationException();
3467 }
3468
3469 public int size()
3470 {
3471 return m.size();
3472 }
3473
3474 public String toString()
3475 {
3476 return m.toString();
3477 }
3478
3479 public Collection values()
3480 {
3481 if (values == null)
3482 values = new UnmodifiableCollection(m.values());
3483 return values;
3484 }
3485 } // class UnmodifiableMap
3486
3487 /**
3488 * Returns an unmodifiable view of the given set. This allows
3489 * "read-only" access, although changes in the backing set show up
3490 * in this view. Attempts to modify the set directly or via iterators
3491 * will fail with {@link UnsupportedOperationException}.
3492 * <p>
3493 *
3494 * The returned Set implements Serializable, but can only be serialized if
3495 * the set it wraps is likewise Serializable.
3496 *
3497 * @param s the set to wrap
3498 * @return a read-only view of the set
3499 * @see Serializable
3500 */
3501 public static Set unmodifiableSet(Set s)
3502 {
3503 return new UnmodifiableSet(s);
3504 }
3505
3506 /**
3507 * The implementation of {@link #unmodifiableSet(Set)}. This class
3508 * name is required for compatibility with Sun's JDK serializability.
3509 *
3510 * @author Eric Blake <ebb9@email.byu.edu>
3511 */
3512 private static class UnmodifiableSet extends UnmodifiableCollection
3513 implements Set
3514 {
3515 /**
3516 * Compatible with JDK 1.4.
3517 */
3518 private static final long serialVersionUID = -9215047833775013803L;
3519
3520 /**
3521 * Wrap a given set.
3522 * @param s the set to wrap
3523 * @throws NullPointerException if s is null
3524 */
3525 UnmodifiableSet(Set s)
3526 {
3527 super(s);
3528 }
3529
3530 public boolean equals(Object o)
3531 {
3532 return c.equals(o);
3533 }
3534
3535 public int hashCode()
3536 {
3537 return c.hashCode();
3538 }
3539 } // class UnmodifiableSet
3540
3541 /**
3542 * Returns an unmodifiable view of the given sorted map. This allows
3543 * "read-only" access, although changes in the backing map show up in this
3544 * view. Attempts to modify the map directly, via subviews, via collection
3545 * views, or iterators, will fail with {@link UnsupportedOperationException}.
3546 * <p>
3547 *
3548 * The returned SortedMap implements Serializable, but can only be
3549 * serialized if the map it wraps is likewise Serializable.
3550 *
3551 * @param m the map to wrap
3552 * @return a read-only view of the map
3553 * @see Serializable
3554 */
3555 public static SortedMap unmodifiableSortedMap(SortedMap m)
3556 {
3557 return new UnmodifiableSortedMap(m);
3558 }
3559
3560 /**
3561 * The implementation of {@link #unmodifiableSortedMap(SortedMap)}. This
3562 * class name is required for compatibility with Sun's JDK serializability.
3563 *
3564 * @author Eric Blake <ebb9@email.byu.edu>
3565 */
3566 private static class UnmodifiableSortedMap extends UnmodifiableMap
3567 implements SortedMap
3568 {
3569 /**
3570 * Compatible with JDK 1.4.
3571 */
3572 private static final long serialVersionUID = -8806743815996713206L;
3573
3574 /**
3575 * The wrapped map; stored both here and in the superclass to avoid
3576 * excessive casting.
3577 * @serial the wrapped map
3578 */
3579 private final SortedMap sm;
3580
3581 /**
3582 * Wrap a given map.
3583 * @param sm the map to wrap
3584 * @throws NullPointerException if sm is null
3585 */
3586 UnmodifiableSortedMap(SortedMap sm)
3587 {
3588 super(sm);
3589 this.sm = sm;
3590 }
3591
3592 public Comparator comparator()
3593 {
3594 return sm.comparator();
3595 }
3596
3597 public Object firstKey()
3598 {
3599 return sm.firstKey();
3600 }
3601
3602 public SortedMap headMap(Object toKey)
3603 {
3604 return new UnmodifiableSortedMap(sm.headMap(toKey));
3605 }
3606
3607 public Object lastKey()
3608 {
3609 return sm.lastKey();
3610 }
3611
3612 public SortedMap subMap(Object fromKey, Object toKey)
3613 {
3614 return new UnmodifiableSortedMap(sm.subMap(fromKey, toKey));
3615 }
3616
3617 public SortedMap tailMap(Object fromKey)
3618 {
3619 return new UnmodifiableSortedMap(sm.tailMap(fromKey));
3620 }
3621 } // class UnmodifiableSortedMap
3622
3623 /**
3624 * Returns an unmodifiable view of the given sorted set. This allows
3625 * "read-only" access, although changes in the backing set show up
3626 * in this view. Attempts to modify the set directly, via subsets, or via
3627 * iterators, will fail with {@link UnsupportedOperationException}.
3628 * <p>
3629 *
3630 * The returns SortedSet implements Serializable, but can only be
3631 * serialized if the set it wraps is likewise Serializable.
3632 *
3633 * @param s the set to wrap
3634 * @return a read-only view of the set
3635 * @see Serializable
3636 */
3637 public static SortedSet unmodifiableSortedSet(SortedSet s)
3638 {
3639 return new UnmodifiableSortedSet(s);
3640 }
3641
3642 /**
3643 * The implementation of {@link #synchronizedSortedMap(SortedMap)}. This
3644 * class name is required for compatibility with Sun's JDK serializability.
3645 *
3646 * @author Eric Blake <ebb9@email.byu.edu>
3647 */
3648 private static class UnmodifiableSortedSet extends UnmodifiableSet
3649 implements SortedSet
3650 {
3651 /**
3652 * Compatible with JDK 1.4.
3653 */
3654 private static final long serialVersionUID = -4929149591599911165L;
3655
3656 /**
3657 * The wrapped set; stored both here and in the superclass to avoid
3658 * excessive casting.
3659 * @serial the wrapped set
3660 */
3661 private SortedSet ss;
3662
3663 /**
3664 * Wrap a given set.
3665 * @param ss the set to wrap
3666 * @throws NullPointerException if ss is null
3667 */
3668 UnmodifiableSortedSet(SortedSet ss)
3669 {
3670 super(ss);
3671 this.ss = ss;
3672 }
3673
3674 public Comparator comparator()
3675 {
3676 return ss.comparator();
3677 }
3678
3679 public Object first()
3680 {
3681 return ss.first();
3682 }
3683
3684 public SortedSet headSet(Object toElement)
3685 {
3686 return new UnmodifiableSortedSet(ss.headSet(toElement));
3687 }
3688
3689 public Object last()
3690 {
3691 return ss.last();
3692 }
3693
3694 public SortedSet subSet(Object fromElement, Object toElement)
3695 {
3696 return new UnmodifiableSortedSet(ss.subSet(fromElement, toElement));
3697 }
3698
3699 public SortedSet tailSet(Object fromElement)
3700 {
3701 return new UnmodifiableSortedSet(ss.tailSet(fromElement));
3702 }
3703 } // class UnmodifiableSortedSet
3704} // class Collections
Note: See TracBrowser for help on using the repository browser.