FSF GCC merge 02/23/03
[official-gcc.git] / libjava / java / util / Collections.java
blob815afccc80721c4224625a9aec3e1ca98a572f47
1 /* Collections.java -- Utility class with methods to operate on collections
2 Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package java.util;
41 import java.io.Serializable;
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>
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.
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
72 public class Collections
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.
80 private static final int LARGE_LIST_SIZE = 16;
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.
89 * @param l the list to check
90 * @return true if it should be treated as sequential-access
92 private static boolean isSequential(List l)
94 return ! (l instanceof RandomAccess) && l.size() > LARGE_LIST_SIZE;
97 /**
98 * This class is non-instantiable.
100 private Collections()
105 * An immutable, serializable, empty Set.
106 * @see Serializable
108 public static final Set EMPTY_SET = new EmptySet();
111 * The implementation of {@link #EMPTY_SET}. This class name is required
112 * for compatibility with Sun's JDK serializability.
114 * @author Eric Blake <ebb9@email.byu.edu>
116 private static final class EmptySet extends AbstractSet
117 implements Serializable
120 * Compatible with JDK 1.4.
122 private static final long serialVersionUID = 1582296315990362920L;
125 * A private constructor adds overhead.
127 EmptySet()
132 * The size: always 0!
134 public int size()
136 return 0;
140 * Returns an iterator that does not iterate.
142 // This is really cheating! I think it's perfectly valid, though.
143 public Iterator iterator()
145 return EMPTY_LIST.iterator();
148 // The remaining methods are optional, but provide a performance
149 // advantage by not allocating unnecessary iterators in AbstractSet.
151 * The empty set never contains anything.
153 public boolean contains(Object o)
155 return false;
159 * This is true only if the given collection is also empty.
161 public boolean containsAll(Collection c)
163 return c.isEmpty();
167 * Equal only if the other set is empty.
169 public boolean equals(Object o)
171 return o instanceof Set && ((Set) o).isEmpty();
175 * The hashcode is always 0.
177 public int hashCode()
179 return 0;
183 * Always succeeds with false result.
185 public boolean remove(Object o)
187 return false;
191 * Always succeeds with false result.
193 public boolean removeAll(Collection c)
195 return false;
199 * Always succeeds with false result.
201 public boolean retainAll(Collection c)
203 return false;
207 * The array is always empty.
209 public Object[] toArray()
211 return new Object[0];
215 * We don't even need to use reflection!
217 public Object[] toArray(Object[] a)
219 if (a.length > 0)
220 a[0] = null;
221 return a;
225 * The string never changes.
227 public String toString()
229 return "[]";
231 } // class EmptySet
234 * An immutable, serializable, empty List, which implements RandomAccess.
235 * @see Serializable
236 * @see RandomAccess
238 public static final List EMPTY_LIST = new EmptyList();
241 * The implementation of {@link #EMPTY_LIST}. This class name is required
242 * for compatibility with Sun's JDK serializability.
244 * @author Eric Blake <ebb9@email.byu.edu>
246 private static final class EmptyList extends AbstractList
247 implements Serializable, RandomAccess
250 * Compatible with JDK 1.4.
252 private static final long serialVersionUID = 8842843931221139166L;
255 * A private constructor adds overhead.
257 EmptyList()
262 * The size is always 0.
264 public int size()
266 return 0;
270 * No matter the index, it is out of bounds.
272 public Object get(int index)
274 throw new IndexOutOfBoundsException();
277 // The remaining methods are optional, but provide a performance
278 // advantage by not allocating unnecessary iterators in AbstractList.
280 * Never contains anything.
282 public boolean contains(Object o)
284 return false;
288 * This is true only if the given collection is also empty.
290 public boolean containsAll(Collection c)
292 return c.isEmpty();
296 * Equal only if the other set is empty.
298 public boolean equals(Object o)
300 return o instanceof List && ((List) o).isEmpty();
304 * The hashcode is always 1.
306 public int hashCode()
308 return 1;
312 * Returns -1.
314 public int indexOf(Object o)
316 return -1;
320 * Returns -1.
322 public int lastIndexOf(Object o)
324 return -1;
328 * Always succeeds with false result.
330 public boolean remove(Object o)
332 return false;
336 * Always succeeds with false result.
338 public boolean removeAll(Collection c)
340 return false;
344 * Always succeeds with false result.
346 public boolean retainAll(Collection c)
348 return false;
352 * The array is always empty.
354 public Object[] toArray()
356 return new Object[0];
360 * We don't even need to use reflection!
362 public Object[] toArray(Object[] a)
364 if (a.length > 0)
365 a[0] = null;
366 return a;
370 * The string never changes.
372 public String toString()
374 return "[]";
376 } // class EmptyList
379 * An immutable, serializable, empty Map.
380 * @see Serializable
382 public static final Map EMPTY_MAP = new EmptyMap();
385 * The implementation of {@link #EMPTY_MAP}. This class name is required
386 * for compatibility with Sun's JDK serializability.
388 * @author Eric Blake <ebb9@email.byu.edu>
390 private static final class EmptyMap extends AbstractMap
391 implements Serializable
394 * Compatible with JDK 1.4.
396 private static final long serialVersionUID = 6428348081105594320L;
399 * A private constructor adds overhead.
401 EmptyMap()
406 * There are no entries.
408 public Set entrySet()
410 return EMPTY_SET;
413 // The remaining methods are optional, but provide a performance
414 // advantage by not allocating unnecessary iterators in AbstractMap.
416 * No entries!
418 public boolean containsKey(Object key)
420 return false;
424 * No entries!
426 public boolean containsValue(Object value)
428 return false;
432 * Equal to all empty maps.
434 public boolean equals(Object o)
436 return o instanceof Map && ((Map) o).isEmpty();
440 * No mappings, so this returns null.
442 public Object get(Object o)
444 return null;
448 * The hashcode is always 0.
450 public int hashCode()
452 return 0;
456 * No entries.
458 public Set keySet()
460 return EMPTY_SET;
464 * Remove always succeeds, with null result.
466 public Object remove(Object o)
468 return null;
472 * Size is always 0.
474 public int size()
476 return 0;
480 * No entries. Technically, EMPTY_SET, while more specific than a general
481 * Collection, will work. Besides, that's what the JDK uses!
483 public Collection values()
485 return EMPTY_SET;
489 * The string never changes.
491 public String toString()
493 return "[]";
495 } // class EmptyMap
499 * Compare two objects with or without a Comparator. If c is null, uses the
500 * natural ordering. Slightly slower than doing it inline if the JVM isn't
501 * clever, but worth it for removing a duplicate of the search code.
502 * Note: This code is also used in Arrays (for sort as well as search).
504 static final int compare(Object o1, Object o2, Comparator c)
506 return c == null ? ((Comparable) o1).compareTo(o2) : c.compare(o1, o2);
510 * Perform a binary search of a List for a key, using the natural ordering of
511 * the elements. The list must be sorted (as by the sort() method) - if it is
512 * not, the behavior of this method is undefined, and may be an infinite
513 * loop. Further, the key must be comparable with every item in the list. If
514 * the list contains the key more than once, any one of them may be found.
515 * <p>
517 * This algorithm behaves in log(n) time for {@link RandomAccess} lists,
518 * and uses a linear search with O(n) link traversals and log(n) comparisons
519 * with {@link AbstractSequentialList} lists. Note: although the
520 * specification allows for an infinite loop if the list is unsorted, it will
521 * not happen in this (Classpath) implementation.
523 * @param l the list to search (must be sorted)
524 * @param key the value to search for
525 * @return the index at which the key was found, or -n-1 if it was not
526 * found, where n is the index of the first value higher than key or
527 * a.length if there is no such value
528 * @throws ClassCastException if key could not be compared with one of the
529 * elements of l
530 * @throws NullPointerException if a null element has compareTo called
531 * @see #sort(List)
533 public static int binarySearch(List l, Object key)
535 return binarySearch(l, key, null);
539 * Perform a binary search of a List for a key, using a supplied Comparator.
540 * The list must be sorted (as by the sort() method with the same Comparator)
541 * - if it is not, the behavior of this method is undefined, and may be an
542 * infinite loop. Further, the key must be comparable with every item in the
543 * list. If the list contains the key more than once, any one of them may be
544 * found. If the comparator is null, the elements' natural ordering is used.
545 * <p>
547 * This algorithm behaves in log(n) time for {@link RandomAccess} lists,
548 * and uses a linear search with O(n) link traversals and log(n) comparisons
549 * with {@link AbstractSequentialList} lists. Note: although the
550 * specification allows for an infinite loop if the list is unsorted, it will
551 * not happen in this (Classpath) implementation.
553 * @param l the list to search (must be sorted)
554 * @param key the value to search for
555 * @param c the comparator by which the list is sorted
556 * @return the index at which the key was found, or -n-1 if it was not
557 * found, where n is the index of the first value higher than key or
558 * a.length if there is no such value
559 * @throws ClassCastException if key could not be compared with one of the
560 * elements of l
561 * @throws NullPointerException if a null element is compared with natural
562 * ordering (only possible when c is null)
563 * @see #sort(List, Comparator)
565 public static int binarySearch(List l, Object key, Comparator c)
567 int pos = 0;
568 int low = 0;
569 int hi = l.size() - 1;
571 // We use a linear search with log(n) comparisons using an iterator
572 // if the list is sequential-access.
573 if (isSequential(l))
575 ListIterator itr = l.listIterator();
576 int i = 0;
577 while (low <= hi)
579 pos = (low + hi) >> 1;
580 if (i < pos)
581 for ( ; i != pos; i++, itr.next());
582 else
583 for ( ; i != pos; i--, itr.previous());
584 final int d = compare(key, itr.next(), c);
585 if (d == 0)
586 return pos;
587 else if (d < 0)
588 hi = pos - 1;
589 else
590 // This gets the insertion point right on the last loop
591 low = ++pos;
594 else
596 while (low <= hi)
598 pos = (low + hi) >> 1;
599 final int d = compare(key, l.get(pos), c);
600 if (d == 0)
601 return pos;
602 else if (d < 0)
603 hi = pos - 1;
604 else
605 // This gets the insertion point right on the last loop
606 low = ++pos;
610 // If we failed to find it, we do the same whichever search we did.
611 return -pos - 1;
615 * Copy one list to another. If the destination list is longer than the
616 * source list, the remaining elements are unaffected. This method runs in
617 * linear time.
619 * @param dest the destination list
620 * @param source the source list
621 * @throws IndexOutOfBoundsException if the destination list is shorter
622 * than the source list (the destination will be unmodified)
623 * @throws UnsupportedOperationException if dest.listIterator() does not
624 * support the set operation
626 public static void copy(List dest, List source)
628 int pos = source.size();
629 if (dest.size() < pos)
630 throw new IndexOutOfBoundsException("Source does not fit in dest");
632 Iterator i1 = source.iterator();
633 ListIterator i2 = dest.listIterator();
635 while (--pos >= 0)
637 i2.next();
638 i2.set(i1.next());
643 * Returns an Enumeration over a collection. This allows interoperability
644 * with legacy APIs that require an Enumeration as input.
646 * @param c the Collection to iterate over
647 * @return an Enumeration backed by an Iterator over c
649 public static Enumeration enumeration(Collection c)
651 final Iterator i = c.iterator();
652 return new Enumeration()
654 public final boolean hasMoreElements()
656 return i.hasNext();
658 public final Object nextElement()
660 return i.next();
666 * Replace every element of a list with a given value. This method runs in
667 * linear time.
669 * @param l the list to fill.
670 * @param val the object to vill the list with.
671 * @throws UnsupportedOperationException if l.listIterator() does not
672 * support the set operation.
674 public static void fill(List l, Object val)
676 ListIterator itr = l.listIterator();
677 for (int i = l.size() - 1; i >= 0; --i)
679 itr.next();
680 itr.set(val);
685 * Returns the starting index where the specified sublist first occurs
686 * in a larger list, or -1 if there is no matching position. If
687 * <code>target.size() &gt; source.size()</code>, this returns -1,
688 * otherwise this implementation uses brute force, checking for
689 * <code>source.sublist(i, i + target.size()).equals(target)</code>
690 * for all possible i.
692 * @param source the list to search
693 * @param target the sublist to search for
694 * @return the index where found, or -1
695 * @since 1.4
697 public static int indexOfSubList(List source, List target)
699 int ssize = source.size();
700 for (int i = 0, j = target.size(); j <= ssize; i++, j++)
701 if (source.subList(i, j).equals(target))
702 return i;
703 return -1;
707 * Returns the starting index where the specified sublist last occurs
708 * in a larger list, or -1 if there is no matching position. If
709 * <code>target.size() &gt; source.size()</code>, this returns -1,
710 * otherwise this implementation uses brute force, checking for
711 * <code>source.sublist(i, i + target.size()).equals(target)</code>
712 * for all possible i.
714 * @param source the list to search
715 * @param target the sublist to search for
716 * @return the index where found, or -1
717 * @since 1.4
719 public static int lastIndexOfSubList(List source, List target)
721 int ssize = source.size();
722 for (int i = ssize - target.size(), j = ssize; i >= 0; i--, j--)
723 if (source.subList(i, j).equals(target))
724 return i;
725 return -1;
729 * Returns an ArrayList holding the elements visited by a given
730 * Enumeration. This method exists for interoperability between legacy
731 * APIs and the new Collection API.
733 * @param e the enumeration to put in a list
734 * @return a list containing the enumeration elements
735 * @see ArrayList
736 * @since 1.4
738 public static ArrayList list(Enumeration e)
740 ArrayList l = new ArrayList();
741 while (e.hasMoreElements())
742 l.add(e.nextElement());
743 return l;
747 * Find the maximum element in a Collection, according to the natural
748 * ordering of the elements. This implementation iterates over the
749 * Collection, so it works in linear time.
751 * @param c the Collection to find the maximum element of
752 * @return the maximum element of c
753 * @exception NoSuchElementException if c is empty
754 * @exception ClassCastException if elements in c are not mutually comparable
755 * @exception NullPointerException if null.compareTo is called
757 public static Object max(Collection c)
759 return max(c, null);
763 * Find the maximum element in a Collection, according to a specified
764 * Comparator. This implementation iterates over the Collection, so it
765 * works in linear time.
767 * @param c the Collection to find the maximum element of
768 * @param order the Comparator to order the elements by, or null for natural
769 * ordering
770 * @return the maximum element of c
771 * @throws NoSuchElementException if c is empty
772 * @throws ClassCastException if elements in c are not mutually comparable
773 * @throws NullPointerException if null is compared by natural ordering
774 * (only possible when order is null)
776 public static Object max(Collection c, Comparator order)
778 Iterator itr = c.iterator();
779 Object max = itr.next(); // throws NoSuchElementException
780 int csize = c.size();
781 for (int i = 1; i < csize; i++)
783 Object o = itr.next();
784 if (compare(max, o, order) < 0)
785 max = o;
787 return max;
791 * Find the minimum element in a Collection, according to the natural
792 * ordering of the elements. This implementation iterates over the
793 * Collection, so it works in linear time.
795 * @param c the Collection to find the minimum element of
796 * @return the minimum element of c
797 * @throws NoSuchElementException if c is empty
798 * @throws ClassCastException if elements in c are not mutually comparable
799 * @throws NullPointerException if null.compareTo is called
801 public static Object min(Collection c)
803 return min(c, null);
807 * Find the minimum element in a Collection, according to a specified
808 * Comparator. This implementation iterates over the Collection, so it
809 * works in linear time.
811 * @param c the Collection to find the minimum element of
812 * @param order the Comparator to order the elements by, or null for natural
813 * ordering
814 * @return the minimum element of c
815 * @throws NoSuchElementException if c is empty
816 * @throws ClassCastException if elements in c are not mutually comparable
817 * @throws NullPointerException if null is compared by natural ordering
818 * (only possible when order is null)
820 public static Object min(Collection c, Comparator order)
822 Iterator itr = c.iterator();
823 Object min = itr.next(); // throws NoSuchElementExcception
824 int csize = c.size();
825 for (int i = 1; i < csize; i++)
827 Object o = itr.next();
828 if (compare(min, o, order) > 0)
829 min = o;
831 return min;
835 * Creates an immutable list consisting of the same object repeated n times.
836 * The returned object is tiny, consisting of only a single reference to the
837 * object and a count of the number of elements. It is Serializable, and
838 * implements RandomAccess. You can use it in tandem with List.addAll for
839 * fast list construction.
841 * @param n the number of times to repeat the object
842 * @param o the object to repeat
843 * @return a List consisting of n copies of o
844 * @throws IllegalArgumentException if n &lt; 0
845 * @see List#addAll(Collection)
846 * @see Serializable
847 * @see RandomAccess
849 public static List nCopies(final int n, final Object o)
851 return new CopiesList(n, o);
855 * The implementation of {@link #nCopies(int, Object)}. This class name
856 * is required for compatibility with Sun's JDK serializability.
858 * @author Eric Blake <ebb9@email.byu.edu>
860 private static final class CopiesList extends AbstractList
861 implements Serializable, RandomAccess
864 * Compatible with JDK 1.4.
866 private static final long serialVersionUID = 2739099268398711800L;
869 * The count of elements in this list.
870 * @serial the list size
872 private final int n;
875 * The repeated list element.
876 * @serial the list contents
878 private final Object element;
881 * Constructs the list.
883 * @param n the count
884 * @param o the object
885 * @throws IllegalArgumentException if n &lt; 0
887 CopiesList(int n, Object o)
889 if (n < 0)
890 throw new IllegalArgumentException();
891 this.n = n;
892 element = o;
896 * The size is fixed.
898 public int size()
900 return n;
904 * The same element is returned.
906 public Object get(int index)
908 if (index < 0 || index >= n)
909 throw new IndexOutOfBoundsException();
910 return element;
913 // The remaining methods are optional, but provide a performance
914 // advantage by not allocating unnecessary iterators in AbstractList.
916 * This list only contains one element.
918 public boolean contains(Object o)
920 return n > 0 && equals(o, element);
924 * The index is either 0 or -1.
926 public int indexOf(Object o)
928 return (n > 0 && equals(o, element)) ? 0 : -1;
932 * The index is either n-1 or -1.
934 public int lastIndexOf(Object o)
936 return equals(o, element) ? n - 1 : -1;
940 * A subList is just another CopiesList.
942 public List subList(int from, int to)
944 if (from < 0 || to > n)
945 throw new IndexOutOfBoundsException();
946 return new CopiesList(to - from, element);
950 * The array is easy.
952 public Object[] toArray()
954 Object[] a = new Object[n];
955 Arrays.fill(a, element);
956 return a;
960 * The string is easy to generate.
962 public String toString()
964 StringBuffer r = new StringBuffer("{");
965 for (int i = n - 1; --i > 0; )
966 r.append(element).append(", ");
967 r.append(element).append("}");
968 return r.toString();
970 } // class CopiesList
973 * Replace all instances of one object with another in the specified list.
974 * The list does not change size. An element e is replaced if
975 * <code>oldval == null ? e == null : oldval.equals(e)</code>.
977 * @param list the list to iterate over
978 * @param oldval the element to replace
979 * @param newval the new value for the element
980 * @return true if a replacement occurred
981 * @throws UnsupportedOperationException if the list iterator does not allow
982 * for the set operation
983 * @throws ClassCastException newval is of a type which cannot be added
984 * to the list
985 * @throws IllegalArgumentException some other aspect of newval stops
986 * it being added to the list
987 * @since 1.4
989 public static boolean replaceAll(List list, Object oldval, Object newval)
991 ListIterator itr = list.listIterator();
992 boolean replace_occured = false;
993 for (int i = list.size(); --i >= 0; )
994 if (AbstractCollection.equals(oldval, itr.next()))
996 itr.set(newval);
997 replace_occured = true;
999 return replace_occured;
1003 * Reverse a given list. This method works in linear time.
1005 * @param l the list to reverse
1006 * @throws UnsupportedOperationException if l.listIterator() does not
1007 * support the set operation
1009 public static void reverse(List l)
1011 ListIterator i1 = l.listIterator();
1012 int pos1 = 1;
1013 int pos2 = l.size();
1014 ListIterator i2 = l.listIterator(pos2);
1015 while (pos1 < pos2)
1017 Object o = i1.next();
1018 i1.set(i2.previous());
1019 i2.set(o);
1020 ++pos1;
1021 --pos2;
1026 * Get a comparator that implements the reverse of natural ordering. In
1027 * other words, this sorts Comparable objects opposite of how their
1028 * compareTo method would sort. This makes it easy to sort into reverse
1029 * order, by simply passing Collections.reverseOrder() to the sort method.
1030 * The return value of this method is Serializable.
1032 * @return a comparator that imposes reverse natural ordering
1033 * @see Comparable
1034 * @see Serializable
1036 public static Comparator reverseOrder()
1038 return rcInstance;
1042 * The object for {@link #reverseOrder()}.
1044 static private final ReverseComparator rcInstance = new ReverseComparator();
1047 * The implementation of {@link #reverseOrder()}. This class name
1048 * is required for compatibility with Sun's JDK serializability.
1050 * @author Eric Blake <ebb9@email.byu.edu>
1052 private static final class ReverseComparator
1053 implements Comparator, Serializable
1056 * Compatible with JDK 1.4.
1058 static private final long serialVersionUID = 7207038068494060240L;
1061 * A private constructor adds overhead.
1063 ReverseComparator()
1068 * Compare two objects in reverse natural order.
1070 * @param a the first object
1071 * @param b the second object
1072 * @return &lt;, ==, or &gt; 0 according to b.compareTo(a)
1074 public int compare(Object a, Object b)
1076 return ((Comparable) b).compareTo(a);
1081 * Rotate the elements in a list by a specified distance. After calling this
1082 * method, the element now at index <code>i</code> was formerly at index
1083 * <code>(i - distance) mod list.size()</code>. The list size is unchanged.
1084 * <p>
1086 * For example, suppose a list contains <code>[t, a, n, k, s]</code>. After
1087 * either <code>Collections.rotate(l, 4)</code> or
1088 * <code>Collections.rotate(l, -1)</code>, the new contents are
1089 * <code>[s, t, a, n, k]</code>. This can be applied to sublists to rotate
1090 * just a portion of the list. For example, to move element <code>a</code>
1091 * forward two positions in the original example, use
1092 * <code>Collections.rotate(l.subList(1, 3+1), -1)</code>, which will
1093 * result in <code>[t, n, k, a, s]</code>.
1094 * <p>
1096 * If the list is small or implements {@link RandomAccess}, the
1097 * implementation exchanges the first element to its destination, then the
1098 * displaced element, and so on until a circuit has been completed. The
1099 * process is repeated if needed on the second element, and so forth, until
1100 * all elements have been swapped. For large non-random lists, the
1101 * implementation breaks the list into two sublists at index
1102 * <code>-distance mod size</code>, calls {@link #reverse(List)} on the
1103 * pieces, then reverses the overall list.
1105 * @param list the list to rotate
1106 * @param distance the distance to rotate by; unrestricted in value
1107 * @throws UnsupportedOperationException if the list does not support set
1108 * @since 1.4
1110 public static void rotate(List list, int distance)
1112 int size = list.size();
1113 distance %= size;
1114 if (distance == 0)
1115 return;
1116 if (distance < 0)
1117 distance += size;
1119 if (isSequential(list))
1121 reverse(list);
1122 reverse(list.subList(0, distance));
1123 reverse(list.subList(distance, size));
1125 else
1127 // Determine the least common multiple of distance and size, as there
1128 // are (distance / LCM) loops to cycle through.
1129 int a = size;
1130 int lcm = distance;
1131 int b = a % lcm;
1132 while (b != 0)
1134 a = lcm;
1135 lcm = b;
1136 b = a % lcm;
1139 // Now, make the swaps. We must take the remainder every time through
1140 // the inner loop so that we don't overflow i to negative values.
1141 while (--lcm >= 0)
1143 Object o = list.get(lcm);
1144 for (int i = lcm + distance; i != lcm; i = (i + distance) % size)
1145 o = list.set(i, o);
1146 list.set(lcm, o);
1152 * Shuffle a list according to a default source of randomness. The algorithm
1153 * used iterates backwards over the list, swapping each element with an
1154 * element randomly selected from the elements in positions less than or
1155 * equal to it (using r.nextInt(int)).
1156 * <p>
1158 * This algorithm would result in a perfectly fair shuffle (that is, each
1159 * element would have an equal chance of ending up in any position) if r were
1160 * a perfect source of randomness. In practice the results are merely very
1161 * close to perfect.
1162 * <p>
1164 * This method operates in linear time. To do this on large lists which do
1165 * not implement {@link RandomAccess}, a temporary array is used to acheive
1166 * this speed, since it would be quadratic access otherwise.
1168 * @param l the list to shuffle
1169 * @throws UnsupportedOperationException if l.listIterator() does not
1170 * support the set operation
1172 public static void shuffle(List l)
1174 if (defaultRandom == null)
1176 synchronized (Collections.class)
1178 if (defaultRandom == null)
1179 defaultRandom = new Random();
1182 shuffle(l, defaultRandom);
1186 * Cache a single Random object for use by shuffle(List). This improves
1187 * performance as well as ensuring that sequential calls to shuffle() will
1188 * not result in the same shuffle order occurring: the resolution of
1189 * System.currentTimeMillis() is not sufficient to guarantee a unique seed.
1191 private static Random defaultRandom = null;
1194 * Shuffle a list according to a given source of randomness. The algorithm
1195 * used iterates backwards over the list, swapping each element with an
1196 * element randomly selected from the elements in positions less than or
1197 * equal to it (using r.nextInt(int)).
1198 * <p>
1200 * This algorithm would result in a perfectly fair shuffle (that is, each
1201 * element would have an equal chance of ending up in any position) if r were
1202 * a perfect source of randomness. In practise (eg if r = new Random()) the
1203 * results are merely very close to perfect.
1204 * <p>
1206 * This method operates in linear time. To do this on large lists which do
1207 * not implement {@link RandomAccess}, a temporary array is used to acheive
1208 * this speed, since it would be quadratic access otherwise.
1210 * @param l the list to shuffle
1211 * @param r the source of randomness to use for the shuffle
1212 * @throws UnsupportedOperationException if l.listIterator() does not
1213 * support the set operation
1215 public static void shuffle(List l, Random r)
1217 int lsize = l.size();
1218 ListIterator i = l.listIterator(lsize);
1219 boolean sequential = isSequential(l);
1220 Object[] a = null; // stores a copy of the list for the sequential case
1222 if (sequential)
1223 a = l.toArray();
1225 for (int pos = lsize - 1; pos > 0; --pos)
1227 // Obtain a random position to swap with. pos + 1 is used so that the
1228 // range of the random number includes the current position.
1229 int swap = r.nextInt(pos + 1);
1231 // Swap the desired element.
1232 Object o;
1233 if (sequential)
1235 o = a[swap];
1236 a[swap] = i.previous();
1238 else
1239 o = l.set(swap, i.previous());
1241 i.set(o);
1247 * Obtain an immutable Set consisting of a single element. The return value
1248 * of this method is Serializable.
1250 * @param o the single element
1251 * @return an immutable Set containing only o
1252 * @see Serializable
1254 public static Set singleton(Object o)
1256 return new SingletonSet(o);
1260 * The implementation of {@link #singleton(Object)}. This class name
1261 * is required for compatibility with Sun's JDK serializability.
1263 * @author Eric Blake <ebb9@email.byu.edu>
1265 private static final class SingletonSet extends AbstractSet
1266 implements Serializable
1269 * Compatible with JDK 1.4.
1271 private static final long serialVersionUID = 3193687207550431679L;
1275 * The single element; package visible for use in nested class.
1276 * @serial the singleton
1278 final Object element;
1281 * Construct a singleton.
1282 * @param o the element
1284 SingletonSet(Object o)
1286 element = o;
1290 * The size: always 1!
1292 public int size()
1294 return 1;
1298 * Returns an iterator over the lone element.
1300 public Iterator iterator()
1302 return new Iterator()
1304 private boolean hasNext = true;
1306 public boolean hasNext()
1308 return hasNext;
1311 public Object next()
1313 if (hasNext)
1315 hasNext = false;
1316 return element;
1318 else
1319 throw new NoSuchElementException();
1322 public void remove()
1324 throw new UnsupportedOperationException();
1329 // The remaining methods are optional, but provide a performance
1330 // advantage by not allocating unnecessary iterators in AbstractSet.
1332 * The set only contains one element.
1334 public boolean contains(Object o)
1336 return equals(o, element);
1340 * This is true if the other collection only contains the element.
1342 public boolean containsAll(Collection c)
1344 Iterator i = c.iterator();
1345 int pos = c.size();
1346 while (--pos >= 0)
1347 if (! equals(i.next(), element))
1348 return false;
1349 return true;
1353 * The hash is just that of the element.
1355 public int hashCode()
1357 return hashCode(element);
1361 * Returning an array is simple.
1363 public Object[] toArray()
1365 return new Object[] {element};
1369 * Obvious string.
1371 public String toString()
1373 return "[" + element + "]";
1375 } // class SingletonSet
1378 * Obtain an immutable List consisting of a single element. The return value
1379 * of this method is Serializable, and implements RandomAccess.
1381 * @param o the single element
1382 * @return an immutable List containing only o
1383 * @see Serializable
1384 * @see RandomAccess
1385 * @since 1.3
1387 public static List singletonList(Object o)
1389 return new SingletonList(o);
1393 * The implementation of {@link #singletonList(Object)}. This class name
1394 * is required for compatibility with Sun's JDK serializability.
1396 * @author Eric Blake <ebb9@email.byu.edu>
1398 private static final class SingletonList extends AbstractList
1399 implements Serializable, RandomAccess
1402 * Compatible with JDK 1.4.
1404 private static final long serialVersionUID = 3093736618740652951L;
1407 * The single element.
1408 * @serial the singleton
1410 private final Object element;
1413 * Construct a singleton.
1414 * @param o the element
1416 SingletonList(Object o)
1418 element = o;
1422 * The size: always 1!
1424 public int size()
1426 return 1;
1430 * Only index 0 is valid.
1432 public Object get(int index)
1434 if (index == 0)
1435 return element;
1436 throw new IndexOutOfBoundsException();
1439 // The remaining methods are optional, but provide a performance
1440 // advantage by not allocating unnecessary iterators in AbstractList.
1442 * The set only contains one element.
1444 public boolean contains(Object o)
1446 return equals(o, element);
1450 * This is true if the other collection only contains the element.
1452 public boolean containsAll(Collection c)
1454 Iterator i = c.iterator();
1455 int pos = c.size();
1456 while (--pos >= 0)
1457 if (! equals(i.next(), element))
1458 return false;
1459 return true;
1463 * Speed up the hashcode computation.
1465 public int hashCode()
1467 return 31 + hashCode(element);
1471 * Either the list has it or not.
1473 public int indexOf(Object o)
1475 return equals(o, element) ? 0 : -1;
1479 * Either the list has it or not.
1481 public int lastIndexOf(Object o)
1483 return equals(o, element) ? 0 : -1;
1487 * Sublists are limited in scope.
1489 public List subList(int from, int to)
1491 if (from == to && (to == 0 || to == 1))
1492 return EMPTY_LIST;
1493 if (from == 0 && to == 1)
1494 return this;
1495 if (from > to)
1496 throw new IllegalArgumentException();
1497 throw new IndexOutOfBoundsException();
1501 * Returning an array is simple.
1503 public Object[] toArray()
1505 return new Object[] {element};
1509 * Obvious string.
1511 public String toString()
1513 return "[" + element + "]";
1515 } // class SingletonList
1518 * Obtain an immutable Map consisting of a single key-value pair.
1519 * The return value of this method is Serializable.
1521 * @param key the single key
1522 * @param value the single value
1523 * @return an immutable Map containing only the single key-value pair
1524 * @see Serializable
1525 * @since 1.3
1527 public static Map singletonMap(Object key, Object value)
1529 return new SingletonMap(key, value);
1533 * The implementation of {@link #singletonMap(Object)}. This class name
1534 * is required for compatibility with Sun's JDK serializability.
1536 * @author Eric Blake <ebb9@email.byu.edu>
1538 private static final class SingletonMap extends AbstractMap
1539 implements Serializable
1542 * Compatible with JDK 1.4.
1544 private static final long serialVersionUID = -6979724477215052911L;
1547 * The single key.
1548 * @serial the singleton key
1550 private final Object k;
1553 * The corresponding value.
1554 * @serial the singleton value
1556 private final Object v;
1559 * Cache the entry set.
1561 private transient Set entries;
1564 * Construct a singleton.
1565 * @param key the key
1566 * @param value the value
1568 SingletonMap(Object key, Object value)
1570 k = key;
1571 v = value;
1575 * There is a single immutable entry.
1577 public Set entrySet()
1579 if (entries == null)
1580 entries = singleton(new AbstractMap.BasicMapEntry(k, v)
1582 public Object setValue(Object o)
1584 throw new UnsupportedOperationException();
1587 return entries;
1590 // The remaining methods are optional, but provide a performance
1591 // advantage by not allocating unnecessary iterators in AbstractMap.
1593 * Single entry.
1595 public boolean containsKey(Object key)
1597 return equals(key, k);
1601 * Single entry.
1603 public boolean containsValue(Object value)
1605 return equals(value, v);
1609 * Single entry.
1611 public Object get(Object key)
1613 return equals(key, k) ? v : null;
1617 * Calculate the hashcode directly.
1619 public int hashCode()
1621 return hashCode(k) ^ hashCode(v);
1625 * Return the keyset.
1627 public Set keySet()
1629 if (keys == null)
1630 keys = singleton(k);
1631 return keys;
1635 * The size: always 1!
1637 public int size()
1639 return 1;
1643 * Return the values. Technically, a singleton, while more specific than
1644 * a general Collection, will work. Besides, that's what the JDK uses!
1646 public Collection values()
1648 if (values == null)
1649 values = singleton(v);
1650 return values;
1654 * Obvious string.
1656 public String toString()
1658 return "{" + k + "=" + v + "}";
1660 } // class SingletonMap
1663 * Sort a list according to the natural ordering of its elements. The list
1664 * must be modifiable, but can be of fixed size. The sort algorithm is
1665 * precisely that used by Arrays.sort(Object[]), which offers guaranteed
1666 * nlog(n) performance. This implementation dumps the list into an array,
1667 * sorts the array, and then iterates over the list setting each element from
1668 * the array.
1670 * @param l the List to sort
1671 * @throws ClassCastException if some items are not mutually comparable
1672 * @throws UnsupportedOperationException if the List is not modifiable
1673 * @throws NullPointerException if some element is null
1674 * @see Arrays#sort(Object[])
1676 public static void sort(List l)
1678 sort(l, null);
1682 * Sort a list according to a specified Comparator. The list must be
1683 * modifiable, but can be of fixed size. The sort algorithm is precisely that
1684 * used by Arrays.sort(Object[], Comparator), which offers guaranteed
1685 * nlog(n) performance. This implementation dumps the list into an array,
1686 * sorts the array, and then iterates over the list setting each element from
1687 * the array.
1689 * @param l the List to sort
1690 * @param c the Comparator specifying the ordering for the elements, or
1691 * null for natural ordering
1692 * @throws ClassCastException if c will not compare some pair of items
1693 * @throws UnsupportedOperationException if the List is not modifiable
1694 * @throws NullPointerException if null is compared by natural ordering
1695 * (only possible when c is null)
1696 * @see Arrays#sort(Object[], Comparator)
1698 public static void sort(List l, Comparator c)
1700 Object[] a = l.toArray();
1701 Arrays.sort(a, c);
1702 ListIterator i = l.listIterator(a.length);
1703 for (int pos = a.length; --pos >= 0; )
1705 i.previous();
1706 i.set(a[pos]);
1711 * Swaps the elements at the specified positions within the list. Equal
1712 * positions have no effect.
1714 * @param l the list to work on
1715 * @param i the first index to swap
1716 * @param j the second index
1717 * @throws UnsupportedOperationException if list.set is not supported
1718 * @throws IndexOutOfBoundsException if either i or j is &lt; 0 or &gt;=
1719 * list.size()
1720 * @since 1.4
1722 public static void swap(List l, int i, int j)
1724 l.set(i, l.set(j, l.get(i)));
1729 * Returns a synchronized (thread-safe) collection wrapper backed by the
1730 * given collection. Notice that element access through the iterators
1731 * is thread-safe, but if the collection can be structurally modified
1732 * (adding or removing elements) then you should synchronize around the
1733 * iteration to avoid non-deterministic behavior:<br>
1734 * <pre>
1735 * Collection c = Collections.synchronizedCollection(new Collection(...));
1736 * ...
1737 * synchronized (c)
1739 * Iterator i = c.iterator();
1740 * while (i.hasNext())
1741 * foo(i.next());
1743 * </pre><p>
1745 * Since the collection might be a List or a Set, and those have incompatible
1746 * equals and hashCode requirements, this relies on Object's implementation
1747 * rather than passing those calls on to the wrapped collection. The returned
1748 * Collection implements Serializable, but can only be serialized if
1749 * the collection it wraps is likewise Serializable.
1751 * @param c the collection to wrap
1752 * @return a synchronized view of the collection
1753 * @see Serializable
1755 public static Collection synchronizedCollection(Collection c)
1757 return new SynchronizedCollection(c);
1761 * The implementation of {@link #synchronizedCollection(Collection)}. This
1762 * class name is required for compatibility with Sun's JDK serializability.
1763 * Package visible, so that collections such as the one for
1764 * Hashtable.values() can specify which object to synchronize on.
1766 * @author Eric Blake <ebb9@email.byu.edu>
1768 static class SynchronizedCollection
1769 implements Collection, Serializable
1772 * Compatible with JDK 1.4.
1774 private static final long serialVersionUID = 3053995032091335093L;
1777 * The wrapped collection. Package visible for use by subclasses.
1778 * @serial the real collection
1780 final Collection c;
1783 * The object to synchronize on. When an instance is created via public
1784 * methods, it will be this; but other uses like SynchronizedMap.values()
1785 * must specify another mutex. Package visible for use by subclasses.
1786 * @serial the lock
1788 final Object mutex;
1791 * Wrap a given collection.
1792 * @param c the collection to wrap
1793 * @throws NullPointerException if c is null
1795 SynchronizedCollection(Collection c)
1797 this.c = c;
1798 mutex = this;
1799 if (c == null)
1800 throw new NullPointerException();
1804 * Called only by trusted code to specify the mutex as well as the
1805 * collection.
1806 * @param sync the mutex
1807 * @param c the collection
1809 SynchronizedCollection(Object sync, Collection c)
1811 this.c = c;
1812 mutex = sync;
1815 public boolean add(Object o)
1817 synchronized (mutex)
1819 return c.add(o);
1823 public boolean addAll(Collection col)
1825 synchronized (mutex)
1827 return c.addAll(col);
1831 public void clear()
1833 synchronized (mutex)
1835 c.clear();
1839 public boolean contains(Object o)
1841 synchronized (mutex)
1843 return c.contains(o);
1847 public boolean containsAll(Collection c1)
1849 synchronized (mutex)
1851 return c.containsAll(c1);
1855 public boolean isEmpty()
1857 synchronized (mutex)
1859 return c.isEmpty();
1863 public Iterator iterator()
1865 synchronized (mutex)
1867 return new SynchronizedIterator(mutex, c.iterator());
1871 public boolean remove(Object o)
1873 synchronized (mutex)
1875 return c.remove(o);
1879 public boolean removeAll(Collection col)
1881 synchronized (mutex)
1883 return c.removeAll(col);
1887 public boolean retainAll(Collection col)
1889 synchronized (mutex)
1891 return c.retainAll(col);
1895 public int size()
1897 synchronized (mutex)
1899 return c.size();
1903 public Object[] toArray()
1905 synchronized (mutex)
1907 return c.toArray();
1911 public Object[] toArray(Object[] a)
1913 synchronized (mutex)
1915 return c.toArray(a);
1919 public String toString()
1921 synchronized (mutex)
1923 return c.toString();
1926 } // class SynchronizedCollection
1929 * The implementation of the various iterator methods in the
1930 * synchronized classes. These iterators must "sync" on the same object
1931 * as the collection they iterate over.
1933 * @author Eric Blake <ebb9@email.byu.edu>
1935 private static class SynchronizedIterator implements Iterator
1938 * The object to synchronize on. Package visible for use by subclass.
1940 final Object mutex;
1943 * The wrapped iterator.
1945 private final Iterator i;
1948 * Only trusted code creates a wrapper, with the specified sync.
1949 * @param sync the mutex
1950 * @param i the wrapped iterator
1952 SynchronizedIterator(Object sync, Iterator i)
1954 this.i = i;
1955 mutex = sync;
1958 public Object next()
1960 synchronized (mutex)
1962 return i.next();
1966 public boolean hasNext()
1968 synchronized (mutex)
1970 return i.hasNext();
1974 public void remove()
1976 synchronized (mutex)
1978 i.remove();
1981 } // class SynchronizedIterator
1984 * Returns a synchronized (thread-safe) list wrapper backed by the
1985 * given list. Notice that element access through the iterators
1986 * is thread-safe, but if the list can be structurally modified
1987 * (adding or removing elements) then you should synchronize around the
1988 * iteration to avoid non-deterministic behavior:<br>
1989 * <pre>
1990 * List l = Collections.synchronizedList(new List(...));
1991 * ...
1992 * synchronized (l)
1994 * Iterator i = l.iterator();
1995 * while (i.hasNext())
1996 * foo(i.next());
1998 * </pre><p>
2000 * The returned List implements Serializable, but can only be serialized if
2001 * the list it wraps is likewise Serializable. In addition, if the wrapped
2002 * list implements RandomAccess, this does too.
2004 * @param l the list to wrap
2005 * @return a synchronized view of the list
2006 * @see Serializable
2007 * @see RandomAccess
2009 public static List synchronizedList(List l)
2011 if (l instanceof RandomAccess)
2012 return new SynchronizedRandomAccessList(l);
2013 return new SynchronizedList(l);
2017 * The implementation of {@link #synchronizedList(List)} for sequential
2018 * lists. This class name is required for compatibility with Sun's JDK
2019 * serializability. Package visible, so that lists such as Vector.subList()
2020 * can specify which object to synchronize on.
2022 * @author Eric Blake <ebb9@email.byu.edu>
2024 static class SynchronizedList extends SynchronizedCollection
2025 implements List
2028 * Compatible with JDK 1.4.
2030 private static final long serialVersionUID = -7754090372962971524L;
2033 * The wrapped list; stored both here and in the superclass to avoid
2034 * excessive casting. Package visible for use by subclass.
2035 * @serial the wrapped list
2037 final List list;
2040 * Wrap a given list.
2041 * @param l the list to wrap
2042 * @throws NullPointerException if l is null
2044 SynchronizedList(List l)
2046 super(l);
2047 list = l;
2051 * Called only by trusted code to specify the mutex as well as the list.
2052 * @param sync the mutex
2053 * @param l the list
2055 SynchronizedList(Object sync, List l)
2057 super(sync, l);
2058 list = l;
2061 public void add(int index, Object o)
2063 synchronized (mutex)
2065 list.add(index, o);
2069 public boolean addAll(int index, Collection c)
2071 synchronized (mutex)
2073 return list.addAll(index, c);
2077 public boolean equals(Object o)
2079 synchronized (mutex)
2081 return list.equals(o);
2085 public Object get(int index)
2087 synchronized (mutex)
2089 return list.get(index);
2093 public int hashCode()
2095 synchronized (mutex)
2097 return list.hashCode();
2101 public int indexOf(Object o)
2103 synchronized (mutex)
2105 return list.indexOf(o);
2109 public int lastIndexOf(Object o)
2111 synchronized (mutex)
2113 return list.lastIndexOf(o);
2117 public ListIterator listIterator()
2119 synchronized (mutex)
2121 return new SynchronizedListIterator(mutex, list.listIterator());
2125 public ListIterator listIterator(int index)
2127 synchronized (mutex)
2129 return new SynchronizedListIterator(mutex, list.listIterator(index));
2133 public Object remove(int index)
2135 synchronized (mutex)
2137 return list.remove(index);
2141 public Object set(int index, Object o)
2143 synchronized (mutex)
2145 return list.set(index, o);
2149 public List subList(int fromIndex, int toIndex)
2151 synchronized (mutex)
2153 return new SynchronizedList(mutex, list.subList(fromIndex, toIndex));
2156 } // class SynchronizedList
2159 * The implementation of {@link #synchronizedList(List)} for random-access
2160 * lists. This class name is required for compatibility with Sun's JDK
2161 * serializability.
2163 * @author Eric Blake <ebb9@email.byu.edu>
2165 private static final class SynchronizedRandomAccessList
2166 extends SynchronizedList implements RandomAccess
2169 * Compatible with JDK 1.4.
2171 private static final long serialVersionUID = 1530674583602358482L;
2174 * Wrap a given list.
2175 * @param l the list to wrap
2176 * @throws NullPointerException if l is null
2178 SynchronizedRandomAccessList(List l)
2180 super(l);
2184 * Called only by trusted code to specify the mutex as well as the
2185 * collection.
2186 * @param sync the mutex
2187 * @param l the list
2189 SynchronizedRandomAccessList(Object sync, List l)
2191 super(sync, l);
2194 public List subList(int fromIndex, int toIndex)
2196 synchronized (mutex)
2198 return new SynchronizedRandomAccessList(mutex,
2199 list.subList(fromIndex,
2200 toIndex));
2203 } // class SynchronizedRandomAccessList
2206 * The implementation of {@link SynchronizedList#listIterator()}. This
2207 * iterator must "sync" on the same object as the list it iterates over.
2209 * @author Eric Blake <ebb9@email.byu.edu>
2211 private static final class SynchronizedListIterator
2212 extends SynchronizedIterator implements ListIterator
2215 * The wrapped iterator, stored both here and in the superclass to
2216 * avoid excessive casting.
2218 private final ListIterator li;
2221 * Only trusted code creates a wrapper, with the specified sync.
2222 * @param sync the mutex
2223 * @param li the wrapped iterator
2225 SynchronizedListIterator(Object sync, ListIterator li)
2227 super(sync, li);
2228 this.li = li;
2231 public void add(Object o)
2233 synchronized (mutex)
2235 li.add(o);
2238 public boolean hasPrevious()
2240 synchronized (mutex)
2242 return li.hasPrevious();
2246 public int nextIndex()
2248 synchronized (mutex)
2250 return li.nextIndex();
2254 public Object previous()
2256 synchronized (mutex)
2258 return li.previous();
2262 public int previousIndex()
2264 synchronized (mutex)
2266 return li.previousIndex();
2270 public void set(Object o)
2272 synchronized (mutex)
2274 li.set(o);
2277 } // class SynchronizedListIterator
2280 * Returns a synchronized (thread-safe) map wrapper backed by the given
2281 * map. Notice that element access through the collection views and their
2282 * iterators are thread-safe, but if the map can be structurally modified
2283 * (adding or removing elements) then you should synchronize around the
2284 * iteration to avoid non-deterministic behavior:<br>
2285 * <pre>
2286 * Map m = Collections.synchronizedMap(new Map(...));
2287 * ...
2288 * Set s = m.keySet(); // safe outside a synchronized block
2289 * synchronized (m) // synch on m, not s
2291 * Iterator i = s.iterator();
2292 * while (i.hasNext())
2293 * foo(i.next());
2295 * </pre><p>
2297 * The returned Map implements Serializable, but can only be serialized if
2298 * the map it wraps is likewise Serializable.
2300 * @param m the map to wrap
2301 * @return a synchronized view of the map
2302 * @see Serializable
2304 public static Map synchronizedMap(Map m)
2306 return new SynchronizedMap(m);
2310 * The implementation of {@link #synchronizedMap(Map)}. This
2311 * class name is required for compatibility with Sun's JDK serializability.
2313 * @author Eric Blake <ebb9@email.byu.edu>
2315 private static class SynchronizedMap implements Map, Serializable
2318 * Compatible with JDK 1.4.
2320 private static final long serialVersionUID = 1978198479659022715L;
2323 * The wrapped map.
2324 * @serial the real map
2326 private final Map m;
2329 * The object to synchronize on. When an instance is created via public
2330 * methods, it will be this; but other uses like
2331 * SynchronizedSortedMap.subMap() must specify another mutex. Package
2332 * visible for use by subclass.
2333 * @serial the lock
2335 final Object mutex;
2338 * Cache the entry set.
2340 private transient Set entries;
2343 * Cache the key set.
2345 private transient Set keys;
2348 * Cache the value collection.
2350 private transient Collection values;
2353 * Wrap a given map.
2354 * @param m the map to wrap
2355 * @throws NullPointerException if m is null
2357 SynchronizedMap(Map m)
2359 this.m = m;
2360 mutex = this;
2361 if (m == null)
2362 throw new NullPointerException();
2366 * Called only by trusted code to specify the mutex as well as the map.
2367 * @param sync the mutex
2368 * @param m the map
2370 SynchronizedMap(Object sync, Map m)
2372 this.m = m;
2373 mutex = sync;
2376 public void clear()
2378 synchronized (mutex)
2380 m.clear();
2384 public boolean containsKey(Object key)
2386 synchronized (mutex)
2388 return m.containsKey(key);
2392 public boolean containsValue(Object value)
2394 synchronized (mutex)
2396 return m.containsValue(value);
2400 // This is one of the ickiest cases of nesting I've ever seen. It just
2401 // means "return a SynchronizedSet, except that the iterator() method
2402 // returns an SynchronizedIterator whose next() method returns a
2403 // synchronized wrapper around its normal return value".
2404 public Set entrySet()
2406 // Define this here to spare some nesting.
2407 class SynchronizedMapEntry implements Map.Entry
2409 final Map.Entry e;
2410 SynchronizedMapEntry(Object o)
2412 e = (Map.Entry) o;
2414 public boolean equals(Object o)
2416 synchronized (mutex)
2418 return e.equals(o);
2421 public Object getKey()
2423 synchronized (mutex)
2425 return e.getKey();
2428 public Object getValue()
2430 synchronized (mutex)
2432 return e.getValue();
2435 public int hashCode()
2437 synchronized (mutex)
2439 return e.hashCode();
2442 public Object setValue(Object value)
2444 synchronized (mutex)
2446 return e.setValue(value);
2449 public String toString()
2451 synchronized (mutex)
2453 return e.toString();
2456 } // class SynchronizedMapEntry
2458 // Now the actual code.
2459 if (entries == null)
2460 synchronized (mutex)
2462 entries = new SynchronizedSet(mutex, m.entrySet())
2464 public Iterator iterator()
2466 synchronized (super.mutex)
2468 return new SynchronizedIterator(super.mutex, c.iterator())
2470 public Object next()
2472 synchronized (super.mutex)
2474 return new SynchronizedMapEntry(super.next());
2482 return entries;
2485 public boolean equals(Object o)
2487 synchronized (mutex)
2489 return m.equals(o);
2493 public Object get(Object key)
2495 synchronized (mutex)
2497 return m.get(key);
2501 public int hashCode()
2503 synchronized (mutex)
2505 return m.hashCode();
2509 public boolean isEmpty()
2511 synchronized (mutex)
2513 return m.isEmpty();
2517 public Set keySet()
2519 if (keys == null)
2520 synchronized (mutex)
2522 keys = new SynchronizedSet(mutex, m.keySet());
2524 return keys;
2527 public Object put(Object key, Object value)
2529 synchronized (mutex)
2531 return m.put(key, value);
2535 public void putAll(Map map)
2537 synchronized (mutex)
2539 m.putAll(map);
2543 public Object remove(Object o)
2545 synchronized (mutex)
2547 return m.remove(o);
2551 public int size()
2553 synchronized (mutex)
2555 return m.size();
2559 public String toString()
2561 synchronized (mutex)
2563 return m.toString();
2567 public Collection values()
2569 if (values == null)
2570 synchronized (mutex)
2572 values = new SynchronizedCollection(mutex, m.values());
2574 return values;
2576 } // class SynchronizedMap
2579 * Returns a synchronized (thread-safe) set wrapper backed by the given
2580 * set. Notice that element access through the iterator is thread-safe, but
2581 * if the set can be structurally modified (adding or removing elements)
2582 * then you should synchronize around the iteration to avoid
2583 * non-deterministic behavior:<br>
2584 * <pre>
2585 * Set s = Collections.synchronizedSet(new Set(...));
2586 * ...
2587 * synchronized (s)
2589 * Iterator i = s.iterator();
2590 * while (i.hasNext())
2591 * foo(i.next());
2593 * </pre><p>
2595 * The returned Set implements Serializable, but can only be serialized if
2596 * the set it wraps is likewise Serializable.
2598 * @param s the set to wrap
2599 * @return a synchronized view of the set
2600 * @see Serializable
2602 public static Set synchronizedSet(Set s)
2604 return new SynchronizedSet(s);
2608 * The implementation of {@link #synchronizedSet(Set)}. This class
2609 * name is required for compatibility with Sun's JDK serializability.
2610 * Package visible, so that sets such as Hashtable.keySet()
2611 * can specify which object to synchronize on.
2613 * @author Eric Blake <ebb9@email.byu.edu>
2615 static class SynchronizedSet extends SynchronizedCollection
2616 implements Set
2619 * Compatible with JDK 1.4.
2621 private static final long serialVersionUID = 487447009682186044L;
2624 * Wrap a given set.
2625 * @param s the set to wrap
2626 * @throws NullPointerException if s is null
2628 SynchronizedSet(Set s)
2630 super(s);
2634 * Called only by trusted code to specify the mutex as well as the set.
2635 * @param sync the mutex
2636 * @param s the set
2638 SynchronizedSet(Object sync, Set s)
2640 super(sync, s);
2643 public boolean equals(Object o)
2645 synchronized (mutex)
2647 return c.equals(o);
2651 public int hashCode()
2653 synchronized (mutex)
2655 return c.hashCode();
2658 } // class SynchronizedSet
2661 * Returns a synchronized (thread-safe) sorted map wrapper backed by the
2662 * given map. Notice that element access through the collection views,
2663 * subviews, and their iterators are thread-safe, but if the map can be
2664 * structurally modified (adding or removing elements) then you should
2665 * synchronize around the iteration to avoid non-deterministic behavior:<br>
2666 * <pre>
2667 * SortedMap m = Collections.synchronizedSortedMap(new SortedMap(...));
2668 * ...
2669 * Set s = m.keySet(); // safe outside a synchronized block
2670 * SortedMap m2 = m.headMap(foo); // safe outside a synchronized block
2671 * Set s2 = m2.keySet(); // safe outside a synchronized block
2672 * synchronized (m) // synch on m, not m2, s or s2
2674 * Iterator i = s.iterator();
2675 * while (i.hasNext())
2676 * foo(i.next());
2677 * i = s2.iterator();
2678 * while (i.hasNext())
2679 * bar(i.next());
2681 * </pre><p>
2683 * The returned SortedMap implements Serializable, but can only be
2684 * serialized if the map it wraps is likewise Serializable.
2686 * @param m the sorted map to wrap
2687 * @return a synchronized view of the sorted map
2688 * @see Serializable
2690 public static SortedMap synchronizedSortedMap(SortedMap m)
2692 return new SynchronizedSortedMap(m);
2696 * The implementation of {@link #synchronizedSortedMap(SortedMap)}. This
2697 * class name is required for compatibility with Sun's JDK serializability.
2699 * @author Eric Blake <ebb9@email.byu.edu>
2701 private static final class SynchronizedSortedMap extends SynchronizedMap
2702 implements SortedMap
2705 * Compatible with JDK 1.4.
2707 private static final long serialVersionUID = -8798146769416483793L;
2710 * The wrapped map; stored both here and in the superclass to avoid
2711 * excessive casting.
2712 * @serial the wrapped map
2714 private final SortedMap sm;
2717 * Wrap a given map.
2718 * @param sm the map to wrap
2719 * @throws NullPointerException if sm is null
2721 SynchronizedSortedMap(SortedMap sm)
2723 super(sm);
2724 this.sm = sm;
2728 * Called only by trusted code to specify the mutex as well as the map.
2729 * @param sync the mutex
2730 * @param sm the map
2732 SynchronizedSortedMap(Object sync, SortedMap sm)
2734 super(sync, sm);
2735 this.sm = sm;
2738 public Comparator comparator()
2740 synchronized (mutex)
2742 return sm.comparator();
2746 public Object firstKey()
2748 synchronized (mutex)
2750 return sm.firstKey();
2754 public SortedMap headMap(Object toKey)
2756 synchronized (mutex)
2758 return new SynchronizedSortedMap(mutex, sm.headMap(toKey));
2762 public Object lastKey()
2764 synchronized (mutex)
2766 return sm.lastKey();
2770 public SortedMap subMap(Object fromKey, Object toKey)
2772 synchronized (mutex)
2774 return new SynchronizedSortedMap(mutex, sm.subMap(fromKey, toKey));
2778 public SortedMap tailMap(Object fromKey)
2780 synchronized (mutex)
2782 return new SynchronizedSortedMap(mutex, sm.tailMap(fromKey));
2785 } // class SynchronizedSortedMap
2788 * Returns a synchronized (thread-safe) sorted set wrapper backed by the
2789 * given set. Notice that element access through the iterator and through
2790 * subviews are thread-safe, but if the set can be structurally modified
2791 * (adding or removing elements) then you should synchronize around the
2792 * iteration to avoid non-deterministic behavior:<br>
2793 * <pre>
2794 * SortedSet s = Collections.synchronizedSortedSet(new SortedSet(...));
2795 * ...
2796 * SortedSet s2 = s.headSet(foo); // safe outside a synchronized block
2797 * synchronized (s) // synch on s, not s2
2799 * Iterator i = s2.iterator();
2800 * while (i.hasNext())
2801 * foo(i.next());
2803 * </pre><p>
2805 * The returned SortedSet implements Serializable, but can only be
2806 * serialized if the set it wraps is likewise Serializable.
2808 * @param s the sorted set to wrap
2809 * @return a synchronized view of the sorted set
2810 * @see Serializable
2812 public static SortedSet synchronizedSortedSet(SortedSet s)
2814 return new SynchronizedSortedSet(s);
2818 * The implementation of {@link #synchronizedSortedSet(SortedSet)}. This
2819 * class name is required for compatibility with Sun's JDK serializability.
2821 * @author Eric Blake <ebb9@email.byu.edu>
2823 private static final class SynchronizedSortedSet extends SynchronizedSet
2824 implements SortedSet
2827 * Compatible with JDK 1.4.
2829 private static final long serialVersionUID = 8695801310862127406L;
2832 * The wrapped set; stored both here and in the superclass to avoid
2833 * excessive casting.
2834 * @serial the wrapped set
2836 private final SortedSet ss;
2839 * Wrap a given set.
2840 * @param ss the set to wrap
2841 * @throws NullPointerException if ss is null
2843 SynchronizedSortedSet(SortedSet ss)
2845 super(ss);
2846 this.ss = ss;
2850 * Called only by trusted code to specify the mutex as well as the set.
2851 * @param sync the mutex
2852 * @param l the list
2854 SynchronizedSortedSet(Object sync, SortedSet ss)
2856 super(sync, ss);
2857 this.ss = ss;
2860 public Comparator comparator()
2862 synchronized (mutex)
2864 return ss.comparator();
2868 public Object first()
2870 synchronized (mutex)
2872 return ss.first();
2876 public SortedSet headSet(Object toElement)
2878 synchronized (mutex)
2880 return new SynchronizedSortedSet(mutex, ss.headSet(toElement));
2884 public Object last()
2886 synchronized (mutex)
2888 return ss.last();
2892 public SortedSet subSet(Object fromElement, Object toElement)
2894 synchronized (mutex)
2896 return new SynchronizedSortedSet(mutex,
2897 ss.subSet(fromElement, toElement));
2901 public SortedSet tailSet(Object fromElement)
2903 synchronized (mutex)
2905 return new SynchronizedSortedSet(mutex, ss.tailSet(fromElement));
2908 } // class SynchronizedSortedSet
2912 * Returns an unmodifiable view of the given collection. This allows
2913 * "read-only" access, although changes in the backing collection show up
2914 * in this view. Attempts to modify the collection directly or via iterators
2915 * will fail with {@link UnsupportedOperationException}.
2916 * <p>
2918 * Since the collection might be a List or a Set, and those have incompatible
2919 * equals and hashCode requirements, this relies on Object's implementation
2920 * rather than passing those calls on to the wrapped collection. The returned
2921 * Collection implements Serializable, but can only be serialized if
2922 * the collection it wraps is likewise Serializable.
2924 * @param c the collection to wrap
2925 * @return a read-only view of the collection
2926 * @see Serializable
2928 public static Collection unmodifiableCollection(Collection c)
2930 return new UnmodifiableCollection(c);
2934 * The implementation of {@link #unmodifiableCollection(Collection)}. This
2935 * class name is required for compatibility with Sun's JDK serializability.
2937 * @author Eric Blake <ebb9@email.byu.edu>
2939 private static class UnmodifiableCollection
2940 implements Collection, Serializable
2943 * Compatible with JDK 1.4.
2945 private static final long serialVersionUID = 1820017752578914078L;
2948 * The wrapped collection. Package visible for use by subclasses.
2949 * @serial the real collection
2951 final Collection c;
2954 * Wrap a given collection.
2955 * @param c the collection to wrap
2956 * @throws NullPointerException if c is null
2958 UnmodifiableCollection(Collection c)
2960 this.c = c;
2961 if (c == null)
2962 throw new NullPointerException();
2965 public boolean add(Object o)
2967 throw new UnsupportedOperationException();
2970 public boolean addAll(Collection c)
2972 throw new UnsupportedOperationException();
2975 public void clear()
2977 throw new UnsupportedOperationException();
2980 public boolean contains(Object o)
2982 return c.contains(o);
2985 public boolean containsAll(Collection c1)
2987 return c.containsAll(c1);
2990 public boolean isEmpty()
2992 return c.isEmpty();
2995 public Iterator iterator()
2997 return new UnmodifiableIterator(c.iterator());
3000 public boolean remove(Object o)
3002 throw new UnsupportedOperationException();
3005 public boolean removeAll(Collection c)
3007 throw new UnsupportedOperationException();
3010 public boolean retainAll(Collection c)
3012 throw new UnsupportedOperationException();
3015 public int size()
3017 return c.size();
3020 public Object[] toArray()
3022 return c.toArray();
3025 public Object[] toArray(Object[] a)
3027 return c.toArray(a);
3030 public String toString()
3032 return c.toString();
3034 } // class UnmodifiableCollection
3037 * The implementation of the various iterator methods in the
3038 * unmodifiable classes.
3040 * @author Eric Blake <ebb9@email.byu.edu>
3042 private static class UnmodifiableIterator implements Iterator
3045 * The wrapped iterator.
3047 private final Iterator i;
3050 * Only trusted code creates a wrapper.
3051 * @param i the wrapped iterator
3053 UnmodifiableIterator(Iterator i)
3055 this.i = i;
3058 public Object next()
3060 return i.next();
3063 public boolean hasNext()
3065 return i.hasNext();
3068 public void remove()
3070 throw new UnsupportedOperationException();
3072 } // class UnmodifiableIterator
3075 * Returns an unmodifiable view of the given list. This allows
3076 * "read-only" access, although changes in the backing list show up
3077 * in this view. Attempts to modify the list directly, via iterators, or
3078 * via sublists, will fail with {@link UnsupportedOperationException}.
3079 * <p>
3081 * The returned List implements Serializable, but can only be serialized if
3082 * the list it wraps is likewise Serializable. In addition, if the wrapped
3083 * list implements RandomAccess, this does too.
3085 * @param l the list to wrap
3086 * @return a read-only view of the list
3087 * @see Serializable
3088 * @see RandomAccess
3090 public static List unmodifiableList(List l)
3092 if (l instanceof RandomAccess)
3093 return new UnmodifiableRandomAccessList(l);
3094 return new UnmodifiableList(l);
3098 * The implementation of {@link #unmodifiableList(List)} for sequential
3099 * lists. This class name is required for compatibility with Sun's JDK
3100 * serializability.
3102 * @author Eric Blake <ebb9@email.byu.edu>
3104 private static class UnmodifiableList extends UnmodifiableCollection
3105 implements List
3108 * Compatible with JDK 1.4.
3110 private static final long serialVersionUID = -283967356065247728L;
3114 * The wrapped list; stored both here and in the superclass to avoid
3115 * excessive casting. Package visible for use by subclass.
3116 * @serial the wrapped list
3118 final List list;
3121 * Wrap a given list.
3122 * @param l the list to wrap
3123 * @throws NullPointerException if l is null
3125 UnmodifiableList(List l)
3127 super(l);
3128 list = l;
3131 public void add(int index, Object o)
3133 throw new UnsupportedOperationException();
3136 public boolean addAll(int index, Collection c)
3138 throw new UnsupportedOperationException();
3141 public boolean equals(Object o)
3143 return list.equals(o);
3146 public Object get(int index)
3148 return list.get(index);
3151 public int hashCode()
3153 return list.hashCode();
3156 public int indexOf(Object o)
3158 return list.indexOf(o);
3161 public int lastIndexOf(Object o)
3163 return list.lastIndexOf(o);
3166 public ListIterator listIterator()
3168 return new UnmodifiableListIterator(list.listIterator());
3171 public ListIterator listIterator(int index)
3173 return new UnmodifiableListIterator(list.listIterator(index));
3176 public Object remove(int index)
3178 throw new UnsupportedOperationException();
3181 public Object set(int index, Object o)
3183 throw new UnsupportedOperationException();
3186 public List subList(int fromIndex, int toIndex)
3188 return unmodifiableList(list.subList(fromIndex, toIndex));
3190 } // class UnmodifiableList
3193 * The implementation of {@link #unmodifiableList(List)} for random-access
3194 * lists. This class name is required for compatibility with Sun's JDK
3195 * serializability.
3197 * @author Eric Blake <ebb9@email.byu.edu>
3199 private static final class UnmodifiableRandomAccessList
3200 extends UnmodifiableList implements RandomAccess
3203 * Compatible with JDK 1.4.
3205 private static final long serialVersionUID = -2542308836966382001L;
3208 * Wrap a given list.
3209 * @param l the list to wrap
3210 * @throws NullPointerException if l is null
3212 UnmodifiableRandomAccessList(List l)
3214 super(l);
3216 } // class UnmodifiableRandomAccessList
3219 * The implementation of {@link UnmodifiableList#listIterator()}.
3221 * @author Eric Blake <ebb9@email.byu.edu>
3223 private static final class UnmodifiableListIterator
3224 extends UnmodifiableIterator implements ListIterator
3227 * The wrapped iterator, stored both here and in the superclass to
3228 * avoid excessive casting.
3230 private final ListIterator li;
3233 * Only trusted code creates a wrapper.
3234 * @param li the wrapped iterator
3236 UnmodifiableListIterator(ListIterator li)
3238 super(li);
3239 this.li = li;
3242 public void add(Object o)
3244 throw new UnsupportedOperationException();
3247 public boolean hasPrevious()
3249 return li.hasPrevious();
3252 public int nextIndex()
3254 return li.nextIndex();
3257 public Object previous()
3259 return li.previous();
3262 public int previousIndex()
3264 return li.previousIndex();
3267 public void set(Object o)
3269 throw new UnsupportedOperationException();
3271 } // class UnmodifiableListIterator
3274 * Returns an unmodifiable view of the given map. This allows "read-only"
3275 * access, although changes in the backing map show up in this view.
3276 * Attempts to modify the map directly, or via collection views or their
3277 * iterators will fail with {@link UnsupportedOperationException}.
3278 * <p>
3280 * The returned Map implements Serializable, but can only be serialized if
3281 * the map it wraps is likewise Serializable.
3283 * @param m the map to wrap
3284 * @return a read-only view of the map
3285 * @see Serializable
3287 public static Map unmodifiableMap(Map m)
3289 return new UnmodifiableMap(m);
3293 * The implementation of {@link #unmodifiableMap(Map)}. This
3294 * class name is required for compatibility with Sun's JDK serializability.
3296 * @author Eric Blake <ebb9@email.byu.edu>
3298 private static class UnmodifiableMap implements Map, Serializable
3301 * Compatible with JDK 1.4.
3303 private static final long serialVersionUID = -1034234728574286014L;
3306 * The wrapped map.
3307 * @serial the real map
3309 private final Map m;
3312 * Cache the entry set.
3314 private transient Set entries;
3317 * Cache the key set.
3319 private transient Set keys;
3322 * Cache the value collection.
3324 private transient Collection values;
3327 * Wrap a given map.
3328 * @param m the map to wrap
3329 * @throws NullPointerException if m is null
3331 UnmodifiableMap(Map m)
3333 this.m = m;
3334 if (m == null)
3335 throw new NullPointerException();
3338 public void clear()
3340 throw new UnsupportedOperationException();
3343 public boolean containsKey(Object key)
3345 return m.containsKey(key);
3348 public boolean containsValue(Object value)
3350 return m.containsValue(value);
3353 public Set entrySet()
3355 if (entries == null)
3356 entries = new UnmodifiableEntrySet(m.entrySet());
3357 return entries;
3361 * The implementation of {@link UnmodifiableMap#entrySet()}. This class
3362 * name is required for compatibility with Sun's JDK serializability.
3364 * @author Eric Blake <ebb9@email.byu.edu>
3366 private static final class UnmodifiableEntrySet extends UnmodifiableSet
3367 implements Serializable
3370 * Compatible with JDK 1.4.
3372 private static final long serialVersionUID = 7854390611657943733L;
3375 * Wrap a given set.
3376 * @param s the set to wrap
3378 UnmodifiableEntrySet(Set s)
3380 super(s);
3383 // The iterator must return unmodifiable map entries.
3384 public Iterator iterator()
3386 return new UnmodifiableIterator(c.iterator())
3388 public Object next()
3390 final Map.Entry e = (Map.Entry) super.next();
3391 return new Map.Entry()
3393 public boolean equals(Object o)
3395 return e.equals(o);
3397 public Object getKey()
3399 return e.getKey();
3401 public Object getValue()
3403 return e.getValue();
3405 public int hashCode()
3407 return e.hashCode();
3409 public Object setValue(Object value)
3411 throw new UnsupportedOperationException();
3413 public String toString()
3415 return e.toString();
3421 } // class UnmodifiableEntrySet
3423 public boolean equals(Object o)
3425 return m.equals(o);
3428 public Object get(Object key)
3430 return m.get(key);
3433 public Object put(Object key, Object value)
3435 throw new UnsupportedOperationException();
3438 public int hashCode()
3440 return m.hashCode();
3443 public boolean isEmpty()
3445 return m.isEmpty();
3448 public Set keySet()
3450 if (keys == null)
3451 keys = new UnmodifiableSet(m.keySet());
3452 return keys;
3455 public void putAll(Map m)
3457 throw new UnsupportedOperationException();
3460 public Object remove(Object o)
3462 throw new UnsupportedOperationException();
3465 public int size()
3467 return m.size();
3470 public String toString()
3472 return m.toString();
3475 public Collection values()
3477 if (values == null)
3478 values = new UnmodifiableCollection(m.values());
3479 return values;
3481 } // class UnmodifiableMap
3484 * Returns an unmodifiable view of the given set. This allows
3485 * "read-only" access, although changes in the backing set show up
3486 * in this view. Attempts to modify the set directly or via iterators
3487 * will fail with {@link UnsupportedOperationException}.
3488 * <p>
3490 * The returned Set implements Serializable, but can only be serialized if
3491 * the set it wraps is likewise Serializable.
3493 * @param s the set to wrap
3494 * @return a read-only view of the set
3495 * @see Serializable
3497 public static Set unmodifiableSet(Set s)
3499 return new UnmodifiableSet(s);
3503 * The implementation of {@link #unmodifiableSet(Set)}. This class
3504 * name is required for compatibility with Sun's JDK serializability.
3506 * @author Eric Blake <ebb9@email.byu.edu>
3508 private static class UnmodifiableSet extends UnmodifiableCollection
3509 implements Set
3512 * Compatible with JDK 1.4.
3514 private static final long serialVersionUID = -9215047833775013803L;
3517 * Wrap a given set.
3518 * @param s the set to wrap
3519 * @throws NullPointerException if s is null
3521 UnmodifiableSet(Set s)
3523 super(s);
3526 public boolean equals(Object o)
3528 return c.equals(o);
3531 public int hashCode()
3533 return c.hashCode();
3535 } // class UnmodifiableSet
3538 * Returns an unmodifiable view of the given sorted map. This allows
3539 * "read-only" access, although changes in the backing map show up in this
3540 * view. Attempts to modify the map directly, via subviews, via collection
3541 * views, or iterators, will fail with {@link UnsupportedOperationException}.
3542 * <p>
3544 * The returned SortedMap implements Serializable, but can only be
3545 * serialized if the map it wraps is likewise Serializable.
3547 * @param m the map to wrap
3548 * @return a read-only view of the map
3549 * @see Serializable
3551 public static SortedMap unmodifiableSortedMap(SortedMap m)
3553 return new UnmodifiableSortedMap(m);
3557 * The implementation of {@link #unmodifiableSortedMap(SortedMap)}. This
3558 * class name is required for compatibility with Sun's JDK serializability.
3560 * @author Eric Blake <ebb9@email.byu.edu>
3562 private static class UnmodifiableSortedMap extends UnmodifiableMap
3563 implements SortedMap
3566 * Compatible with JDK 1.4.
3568 private static final long serialVersionUID = -8806743815996713206L;
3571 * The wrapped map; stored both here and in the superclass to avoid
3572 * excessive casting.
3573 * @serial the wrapped map
3575 private final SortedMap sm;
3578 * Wrap a given map.
3579 * @param sm the map to wrap
3580 * @throws NullPointerException if sm is null
3582 UnmodifiableSortedMap(SortedMap sm)
3584 super(sm);
3585 this.sm = sm;
3588 public Comparator comparator()
3590 return sm.comparator();
3593 public Object firstKey()
3595 return sm.firstKey();
3598 public SortedMap headMap(Object toKey)
3600 return new UnmodifiableSortedMap(sm.headMap(toKey));
3603 public Object lastKey()
3605 return sm.lastKey();
3608 public SortedMap subMap(Object fromKey, Object toKey)
3610 return new UnmodifiableSortedMap(sm.subMap(fromKey, toKey));
3613 public SortedMap tailMap(Object fromKey)
3615 return new UnmodifiableSortedMap(sm.tailMap(fromKey));
3617 } // class UnmodifiableSortedMap
3620 * Returns an unmodifiable view of the given sorted set. This allows
3621 * "read-only" access, although changes in the backing set show up
3622 * in this view. Attempts to modify the set directly, via subsets, or via
3623 * iterators, will fail with {@link UnsupportedOperationException}.
3624 * <p>
3626 * The returns SortedSet implements Serializable, but can only be
3627 * serialized if the set it wraps is likewise Serializable.
3629 * @param s the set to wrap
3630 * @return a read-only view of the set
3631 * @see Serializable
3633 public static SortedSet unmodifiableSortedSet(SortedSet s)
3635 return new UnmodifiableSortedSet(s);
3639 * The implementation of {@link #synchronizedSortedMap(SortedMap)}. This
3640 * class name is required for compatibility with Sun's JDK serializability.
3642 * @author Eric Blake <ebb9@email.byu.edu>
3644 private static class UnmodifiableSortedSet extends UnmodifiableSet
3645 implements SortedSet
3648 * Compatible with JDK 1.4.
3650 private static final long serialVersionUID = -4929149591599911165L;
3653 * The wrapped set; stored both here and in the superclass to avoid
3654 * excessive casting.
3655 * @serial the wrapped set
3657 private SortedSet ss;
3660 * Wrap a given set.
3661 * @param ss the set to wrap
3662 * @throws NullPointerException if ss is null
3664 UnmodifiableSortedSet(SortedSet ss)
3666 super(ss);
3667 this.ss = ss;
3670 public Comparator comparator()
3672 return ss.comparator();
3675 public Object first()
3677 return ss.first();
3680 public SortedSet headSet(Object toElement)
3682 return new UnmodifiableSortedSet(ss.headSet(toElement));
3685 public Object last()
3687 return ss.last();
3690 public SortedSet subSet(Object fromElement, Object toElement)
3692 return new UnmodifiableSortedSet(ss.subSet(fromElement, toElement));
3695 public SortedSet tailSet(Object fromElement)
3697 return new UnmodifiableSortedSet(ss.tailSet(fromElement));
3699 } // class UnmodifiableSortedSet
3700 } // class Collections