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)
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
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
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. */
41 import java.io.Serializable;
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.
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.
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
62 * @author Original author unknown
63 * @author Eric Blake <ebb9@email.byu.edu>
70 * @status updated to 1.4
72 public class Collections
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;
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;
98 * This class is non-instantiable.
100 private Collections()
105 * An immutable, serializable, empty Set.
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.
132 * The size: always 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)
159 * This is true only if the given collection is also empty.
161 public boolean containsAll(Collection c)
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()
183 * Always succeeds with false result.
185 public boolean remove(Object o)
191 * Always succeeds with false result.
193 public boolean removeAll(Collection c)
199 * Always succeeds with false result.
201 public boolean retainAll(Collection c)
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)
225 * The string never changes.
227 public String toString()
234 * An immutable, serializable, empty List, which implements 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.
262 * The size is always 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)
288 * This is true only if the given collection is also empty.
290 public boolean containsAll(Collection c)
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()
314 public int indexOf(Object o)
322 public int lastIndexOf(Object o)
328 * Always succeeds with false result.
330 public boolean remove(Object o)
336 * Always succeeds with false result.
338 public boolean removeAll(Collection c)
344 * Always succeeds with false result.
346 public boolean retainAll(Collection c)
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)
370 * The string never changes.
372 public String toString()
379 * An immutable, serializable, empty Map.
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.
406 * There are no entries.
408 public Set entrySet()
413 // The remaining methods are optional, but provide a performance
414 // advantage by not allocating unnecessary iterators in AbstractMap.
418 public boolean containsKey(Object key)
426 public boolean containsValue(Object value)
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)
448 * The hashcode is always 0.
450 public int hashCode()
464 * Remove always succeeds, with null result.
466 public Object remove(Object o)
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()
489 * The string never changes.
491 public String toString()
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.
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
530 * @throws NullPointerException if a null element has compareTo called
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.
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
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)
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.
575 ListIterator itr = l.listIterator();
577 Object o = itr.next(); // Assumes list is not empty (see isSequential)
578 boolean forward = true;
581 pos = (low + hi) >> 1;
585 itr.next(); // Changing direction first.
586 for ( ; i != pos; i++, o = itr.next());
592 itr.previous(); // Changing direction first.
593 for ( ; i != pos; i--, o = itr.previous());
596 final int d = compare(key, o, c);
602 // This gets the insertion point right on the last loop
610 pos = (low + hi) >> 1;
611 final int d = compare(key, l.get(pos), c);
617 // This gets the insertion point right on the last loop
622 // If we failed to find it, we do the same whichever search we did.
627 * Copy one list to another. If the destination list is longer than the
628 * source list, the remaining elements are unaffected. This method runs in
631 * @param dest the destination list
632 * @param source the source list
633 * @throws IndexOutOfBoundsException if the destination list is shorter
634 * than the source list (the destination will be unmodified)
635 * @throws UnsupportedOperationException if dest.listIterator() does not
636 * support the set operation
638 public static void copy(List dest, List source)
640 int pos = source.size();
641 if (dest.size() < pos)
642 throw new IndexOutOfBoundsException("Source does not fit in dest");
644 Iterator i1 = source.iterator();
645 ListIterator i2 = dest.listIterator();
655 * Returns an Enumeration over a collection. This allows interoperability
656 * with legacy APIs that require an Enumeration as input.
658 * @param c the Collection to iterate over
659 * @return an Enumeration backed by an Iterator over c
661 public static Enumeration enumeration(Collection c)
663 final Iterator i = c.iterator();
664 return new Enumeration()
666 public final boolean hasMoreElements()
670 public final Object nextElement()
678 * Replace every element of a list with a given value. This method runs in
681 * @param l the list to fill.
682 * @param val the object to vill the list with.
683 * @throws UnsupportedOperationException if l.listIterator() does not
684 * support the set operation.
686 public static void fill(List l, Object val)
688 ListIterator itr = l.listIterator();
689 for (int i = l.size() - 1; i >= 0; --i)
697 * Returns the starting index where the specified sublist first occurs
698 * in a larger list, or -1 if there is no matching position. If
699 * <code>target.size() > source.size()</code>, this returns -1,
700 * otherwise this implementation uses brute force, checking for
701 * <code>source.sublist(i, i + target.size()).equals(target)</code>
702 * for all possible i.
704 * @param source the list to search
705 * @param target the sublist to search for
706 * @return the index where found, or -1
709 public static int indexOfSubList(List source, List target)
711 int ssize = source.size();
712 for (int i = 0, j = target.size(); j <= ssize; i++, j++)
713 if (source.subList(i, j).equals(target))
719 * Returns the starting index where the specified sublist last occurs
720 * in a larger list, or -1 if there is no matching position. If
721 * <code>target.size() > source.size()</code>, this returns -1,
722 * otherwise this implementation uses brute force, checking for
723 * <code>source.sublist(i, i + target.size()).equals(target)</code>
724 * for all possible i.
726 * @param source the list to search
727 * @param target the sublist to search for
728 * @return the index where found, or -1
731 public static int lastIndexOfSubList(List source, List target)
733 int ssize = source.size();
734 for (int i = ssize - target.size(), j = ssize; i >= 0; i--, j--)
735 if (source.subList(i, j).equals(target))
741 * Returns an ArrayList holding the elements visited by a given
742 * Enumeration. This method exists for interoperability between legacy
743 * APIs and the new Collection API.
745 * @param e the enumeration to put in a list
746 * @return a list containing the enumeration elements
750 public static ArrayList list(Enumeration e)
752 ArrayList l = new ArrayList();
753 while (e.hasMoreElements())
754 l.add(e.nextElement());
759 * Find the maximum element in a Collection, according to the natural
760 * ordering of the elements. This implementation iterates over the
761 * Collection, so it works in linear time.
763 * @param c the Collection to find the maximum element of
764 * @return the maximum element of c
765 * @exception NoSuchElementException if c is empty
766 * @exception ClassCastException if elements in c are not mutually comparable
767 * @exception NullPointerException if null.compareTo is called
769 public static Object max(Collection c)
775 * Find the maximum element in a Collection, according to a specified
776 * Comparator. This implementation iterates over the Collection, so it
777 * works in linear time.
779 * @param c the Collection to find the maximum element of
780 * @param order the Comparator to order the elements by, or null for natural
782 * @return the maximum element of c
783 * @throws NoSuchElementException if c is empty
784 * @throws ClassCastException if elements in c are not mutually comparable
785 * @throws NullPointerException if null is compared by natural ordering
786 * (only possible when order is null)
788 public static Object max(Collection c, Comparator order)
790 Iterator itr = c.iterator();
791 Object max = itr.next(); // throws NoSuchElementException
792 int csize = c.size();
793 for (int i = 1; i < csize; i++)
795 Object o = itr.next();
796 if (compare(max, o, order) < 0)
803 * Find the minimum element in a Collection, according to the natural
804 * ordering of the elements. This implementation iterates over the
805 * Collection, so it works in linear time.
807 * @param c the Collection to find the minimum element of
808 * @return the minimum element of c
809 * @throws NoSuchElementException if c is empty
810 * @throws ClassCastException if elements in c are not mutually comparable
811 * @throws NullPointerException if null.compareTo is called
813 public static Object min(Collection c)
819 * Find the minimum element in a Collection, according to a specified
820 * Comparator. This implementation iterates over the Collection, so it
821 * works in linear time.
823 * @param c the Collection to find the minimum element of
824 * @param order the Comparator to order the elements by, or null for natural
826 * @return the minimum element of c
827 * @throws NoSuchElementException if c is empty
828 * @throws ClassCastException if elements in c are not mutually comparable
829 * @throws NullPointerException if null is compared by natural ordering
830 * (only possible when order is null)
832 public static Object min(Collection c, Comparator order)
834 Iterator itr = c.iterator();
835 Object min = itr.next(); // throws NoSuchElementExcception
836 int csize = c.size();
837 for (int i = 1; i < csize; i++)
839 Object o = itr.next();
840 if (compare(min, o, order) > 0)
847 * Creates an immutable list consisting of the same object repeated n times.
848 * The returned object is tiny, consisting of only a single reference to the
849 * object and a count of the number of elements. It is Serializable, and
850 * implements RandomAccess. You can use it in tandem with List.addAll for
851 * fast list construction.
853 * @param n the number of times to repeat the object
854 * @param o the object to repeat
855 * @return a List consisting of n copies of o
856 * @throws IllegalArgumentException if n < 0
857 * @see List#addAll(Collection)
861 public static List nCopies(final int n, final Object o)
863 return new CopiesList(n, o);
867 * The implementation of {@link #nCopies(int, Object)}. This class name
868 * is required for compatibility with Sun's JDK serializability.
870 * @author Eric Blake <ebb9@email.byu.edu>
872 private static final class CopiesList extends AbstractList
873 implements Serializable, RandomAccess
876 * Compatible with JDK 1.4.
878 private static final long serialVersionUID = 2739099268398711800L;
881 * The count of elements in this list.
882 * @serial the list size
887 * The repeated list element.
888 * @serial the list contents
890 private final Object element;
893 * Constructs the list.
896 * @param o the object
897 * @throws IllegalArgumentException if n < 0
899 CopiesList(int n, Object o)
902 throw new IllegalArgumentException();
916 * The same element is returned.
918 public Object get(int index)
920 if (index < 0 || index >= n)
921 throw new IndexOutOfBoundsException();
925 // The remaining methods are optional, but provide a performance
926 // advantage by not allocating unnecessary iterators in AbstractList.
928 * This list only contains one element.
930 public boolean contains(Object o)
932 return n > 0 && equals(o, element);
936 * The index is either 0 or -1.
938 public int indexOf(Object o)
940 return (n > 0 && equals(o, element)) ? 0 : -1;
944 * The index is either n-1 or -1.
946 public int lastIndexOf(Object o)
948 return equals(o, element) ? n - 1 : -1;
952 * A subList is just another CopiesList.
954 public List subList(int from, int to)
956 if (from < 0 || to > n)
957 throw new IndexOutOfBoundsException();
958 return new CopiesList(to - from, element);
964 public Object[] toArray()
966 Object[] a = new Object[n];
967 Arrays.fill(a, element);
972 * The string is easy to generate.
974 public String toString()
976 StringBuffer r = new StringBuffer("{");
977 for (int i = n - 1; --i > 0; )
978 r.append(element).append(", ");
979 r.append(element).append("}");
982 } // class CopiesList
985 * Replace all instances of one object with another in the specified list.
986 * The list does not change size. An element e is replaced if
987 * <code>oldval == null ? e == null : oldval.equals(e)</code>.
989 * @param list the list to iterate over
990 * @param oldval the element to replace
991 * @param newval the new value for the element
992 * @return true if a replacement occurred
993 * @throws UnsupportedOperationException if the list iterator does not allow
994 * for the set operation
995 * @throws ClassCastException newval is of a type which cannot be added
997 * @throws IllegalArgumentException some other aspect of newval stops
998 * it being added to the list
1001 public static boolean replaceAll(List list, Object oldval, Object newval)
1003 ListIterator itr = list.listIterator();
1004 boolean replace_occured = false;
1005 for (int i = list.size(); --i >= 0; )
1006 if (AbstractCollection.equals(oldval, itr.next()))
1009 replace_occured = true;
1011 return replace_occured;
1015 * Reverse a given list. This method works in linear time.
1017 * @param l the list to reverse
1018 * @throws UnsupportedOperationException if l.listIterator() does not
1019 * support the set operation
1021 public static void reverse(List l)
1023 ListIterator i1 = l.listIterator();
1025 int pos2 = l.size();
1026 ListIterator i2 = l.listIterator(pos2);
1029 Object o = i1.next();
1030 i1.set(i2.previous());
1038 * Get a comparator that implements the reverse of natural ordering. In
1039 * other words, this sorts Comparable objects opposite of how their
1040 * compareTo method would sort. This makes it easy to sort into reverse
1041 * order, by simply passing Collections.reverseOrder() to the sort method.
1042 * The return value of this method is Serializable.
1044 * @return a comparator that imposes reverse natural ordering
1048 public static Comparator reverseOrder()
1054 * The object for {@link #reverseOrder()}.
1056 static private final ReverseComparator rcInstance = new ReverseComparator();
1059 * The implementation of {@link #reverseOrder()}. This class name
1060 * is required for compatibility with Sun's JDK serializability.
1062 * @author Eric Blake <ebb9@email.byu.edu>
1064 private static final class ReverseComparator
1065 implements Comparator, Serializable
1068 * Compatible with JDK 1.4.
1070 static private final long serialVersionUID = 7207038068494060240L;
1073 * A private constructor adds overhead.
1080 * Compare two objects in reverse natural order.
1082 * @param a the first object
1083 * @param b the second object
1084 * @return <, ==, or > 0 according to b.compareTo(a)
1086 public int compare(Object a, Object b)
1088 return ((Comparable) b).compareTo(a);
1093 * Rotate the elements in a list by a specified distance. After calling this
1094 * method, the element now at index <code>i</code> was formerly at index
1095 * <code>(i - distance) mod list.size()</code>. The list size is unchanged.
1098 * For example, suppose a list contains <code>[t, a, n, k, s]</code>. After
1099 * either <code>Collections.rotate(l, 4)</code> or
1100 * <code>Collections.rotate(l, -1)</code>, the new contents are
1101 * <code>[s, t, a, n, k]</code>. This can be applied to sublists to rotate
1102 * just a portion of the list. For example, to move element <code>a</code>
1103 * forward two positions in the original example, use
1104 * <code>Collections.rotate(l.subList(1, 3+1), -1)</code>, which will
1105 * result in <code>[t, n, k, a, s]</code>.
1108 * If the list is small or implements {@link RandomAccess}, the
1109 * implementation exchanges the first element to its destination, then the
1110 * displaced element, and so on until a circuit has been completed. The
1111 * process is repeated if needed on the second element, and so forth, until
1112 * all elements have been swapped. For large non-random lists, the
1113 * implementation breaks the list into two sublists at index
1114 * <code>-distance mod size</code>, calls {@link #reverse(List)} on the
1115 * pieces, then reverses the overall list.
1117 * @param list the list to rotate
1118 * @param distance the distance to rotate by; unrestricted in value
1119 * @throws UnsupportedOperationException if the list does not support set
1122 public static void rotate(List list, int distance)
1124 int size = list.size();
1133 if (isSequential(list))
1136 reverse(list.subList(0, distance));
1137 reverse(list.subList(distance, size));
1141 // Determine the least common multiple of distance and size, as there
1142 // are (distance / LCM) loops to cycle through.
1153 // Now, make the swaps. We must take the remainder every time through
1154 // the inner loop so that we don't overflow i to negative values.
1157 Object o = list.get(lcm);
1158 for (int i = lcm + distance; i != lcm; i = (i + distance) % size)
1166 * Shuffle a list according to a default source of randomness. The algorithm
1167 * used iterates backwards over the list, swapping each element with an
1168 * element randomly selected from the elements in positions less than or
1169 * equal to it (using r.nextInt(int)).
1172 * This algorithm would result in a perfectly fair shuffle (that is, each
1173 * element would have an equal chance of ending up in any position) if r were
1174 * a perfect source of randomness. In practice the results are merely very
1178 * This method operates in linear time. To do this on large lists which do
1179 * not implement {@link RandomAccess}, a temporary array is used to acheive
1180 * this speed, since it would be quadratic access otherwise.
1182 * @param l the list to shuffle
1183 * @throws UnsupportedOperationException if l.listIterator() does not
1184 * support the set operation
1186 public static void shuffle(List l)
1188 if (defaultRandom == null)
1190 synchronized (Collections.class)
1192 if (defaultRandom == null)
1193 defaultRandom = new Random();
1196 shuffle(l, defaultRandom);
1200 * Cache a single Random object for use by shuffle(List). This improves
1201 * performance as well as ensuring that sequential calls to shuffle() will
1202 * not result in the same shuffle order occurring: the resolution of
1203 * System.currentTimeMillis() is not sufficient to guarantee a unique seed.
1205 private static Random defaultRandom = null;
1208 * Shuffle a list according to a given source of randomness. The algorithm
1209 * used iterates backwards over the list, swapping each element with an
1210 * element randomly selected from the elements in positions less than or
1211 * equal to it (using r.nextInt(int)).
1214 * This algorithm would result in a perfectly fair shuffle (that is, each
1215 * element would have an equal chance of ending up in any position) if r were
1216 * a perfect source of randomness. In practise (eg if r = new Random()) the
1217 * results are merely very close to perfect.
1220 * This method operates in linear time. To do this on large lists which do
1221 * not implement {@link RandomAccess}, a temporary array is used to acheive
1222 * this speed, since it would be quadratic access otherwise.
1224 * @param l the list to shuffle
1225 * @param r the source of randomness to use for the shuffle
1226 * @throws UnsupportedOperationException if l.listIterator() does not
1227 * support the set operation
1229 public static void shuffle(List l, Random r)
1231 int lsize = l.size();
1232 ListIterator i = l.listIterator(lsize);
1233 boolean sequential = isSequential(l);
1234 Object[] a = null; // stores a copy of the list for the sequential case
1239 for (int pos = lsize - 1; pos > 0; --pos)
1241 // Obtain a random position to swap with. pos + 1 is used so that the
1242 // range of the random number includes the current position.
1243 int swap = r.nextInt(pos + 1);
1245 // Swap the desired element.
1250 a[swap] = i.previous();
1253 o = l.set(swap, i.previous());
1261 * Obtain an immutable Set consisting of a single element. The return value
1262 * of this method is Serializable.
1264 * @param o the single element
1265 * @return an immutable Set containing only o
1268 public static Set singleton(Object o)
1270 return new SingletonSet(o);
1274 * The implementation of {@link #singleton(Object)}. This class name
1275 * is required for compatibility with Sun's JDK serializability.
1277 * @author Eric Blake <ebb9@email.byu.edu>
1279 private static final class SingletonSet extends AbstractSet
1280 implements Serializable
1283 * Compatible with JDK 1.4.
1285 private static final long serialVersionUID = 3193687207550431679L;
1289 * The single element; package visible for use in nested class.
1290 * @serial the singleton
1292 final Object element;
1295 * Construct a singleton.
1296 * @param o the element
1298 SingletonSet(Object o)
1304 * The size: always 1!
1312 * Returns an iterator over the lone element.
1314 public Iterator iterator()
1316 return new Iterator()
1318 private boolean hasNext = true;
1320 public boolean hasNext()
1325 public Object next()
1333 throw new NoSuchElementException();
1336 public void remove()
1338 throw new UnsupportedOperationException();
1343 // The remaining methods are optional, but provide a performance
1344 // advantage by not allocating unnecessary iterators in AbstractSet.
1346 * The set only contains one element.
1348 public boolean contains(Object o)
1350 return equals(o, element);
1354 * This is true if the other collection only contains the element.
1356 public boolean containsAll(Collection c)
1358 Iterator i = c.iterator();
1361 if (! equals(i.next(), element))
1367 * The hash is just that of the element.
1369 public int hashCode()
1371 return hashCode(element);
1375 * Returning an array is simple.
1377 public Object[] toArray()
1379 return new Object[] {element};
1385 public String toString()
1387 return "[" + element + "]";
1389 } // class SingletonSet
1392 * Obtain an immutable List consisting of a single element. The return value
1393 * of this method is Serializable, and implements RandomAccess.
1395 * @param o the single element
1396 * @return an immutable List containing only o
1401 public static List singletonList(Object o)
1403 return new SingletonList(o);
1407 * The implementation of {@link #singletonList(Object)}. This class name
1408 * is required for compatibility with Sun's JDK serializability.
1410 * @author Eric Blake <ebb9@email.byu.edu>
1412 private static final class SingletonList extends AbstractList
1413 implements Serializable, RandomAccess
1416 * Compatible with JDK 1.4.
1418 private static final long serialVersionUID = 3093736618740652951L;
1421 * The single element.
1422 * @serial the singleton
1424 private final Object element;
1427 * Construct a singleton.
1428 * @param o the element
1430 SingletonList(Object o)
1436 * The size: always 1!
1444 * Only index 0 is valid.
1446 public Object get(int index)
1450 throw new IndexOutOfBoundsException();
1453 // The remaining methods are optional, but provide a performance
1454 // advantage by not allocating unnecessary iterators in AbstractList.
1456 * The set only contains one element.
1458 public boolean contains(Object o)
1460 return equals(o, element);
1464 * This is true if the other collection only contains the element.
1466 public boolean containsAll(Collection c)
1468 Iterator i = c.iterator();
1471 if (! equals(i.next(), element))
1477 * Speed up the hashcode computation.
1479 public int hashCode()
1481 return 31 + hashCode(element);
1485 * Either the list has it or not.
1487 public int indexOf(Object o)
1489 return equals(o, element) ? 0 : -1;
1493 * Either the list has it or not.
1495 public int lastIndexOf(Object o)
1497 return equals(o, element) ? 0 : -1;
1501 * Sublists are limited in scope.
1503 public List subList(int from, int to)
1505 if (from == to && (to == 0 || to == 1))
1507 if (from == 0 && to == 1)
1510 throw new IllegalArgumentException();
1511 throw new IndexOutOfBoundsException();
1515 * Returning an array is simple.
1517 public Object[] toArray()
1519 return new Object[] {element};
1525 public String toString()
1527 return "[" + element + "]";
1529 } // class SingletonList
1532 * Obtain an immutable Map consisting of a single key-value pair.
1533 * The return value of this method is Serializable.
1535 * @param key the single key
1536 * @param value the single value
1537 * @return an immutable Map containing only the single key-value pair
1541 public static Map singletonMap(Object key, Object value)
1543 return new SingletonMap(key, value);
1547 * The implementation of {@link #singletonMap(Object)}. This class name
1548 * is required for compatibility with Sun's JDK serializability.
1550 * @author Eric Blake <ebb9@email.byu.edu>
1552 private static final class SingletonMap extends AbstractMap
1553 implements Serializable
1556 * Compatible with JDK 1.4.
1558 private static final long serialVersionUID = -6979724477215052911L;
1562 * @serial the singleton key
1564 private final Object k;
1567 * The corresponding value.
1568 * @serial the singleton value
1570 private final Object v;
1573 * Cache the entry set.
1575 private transient Set entries;
1578 * Construct a singleton.
1579 * @param key the key
1580 * @param value the value
1582 SingletonMap(Object key, Object value)
1589 * There is a single immutable entry.
1591 public Set entrySet()
1593 if (entries == null)
1594 entries = singleton(new AbstractMap.BasicMapEntry(k, v)
1596 public Object setValue(Object o)
1598 throw new UnsupportedOperationException();
1604 // The remaining methods are optional, but provide a performance
1605 // advantage by not allocating unnecessary iterators in AbstractMap.
1609 public boolean containsKey(Object key)
1611 return equals(key, k);
1617 public boolean containsValue(Object value)
1619 return equals(value, v);
1625 public Object get(Object key)
1627 return equals(key, k) ? v : null;
1631 * Calculate the hashcode directly.
1633 public int hashCode()
1635 return hashCode(k) ^ hashCode(v);
1639 * Return the keyset.
1644 keys = singleton(k);
1649 * The size: always 1!
1657 * Return the values. Technically, a singleton, while more specific than
1658 * a general Collection, will work. Besides, that's what the JDK uses!
1660 public Collection values()
1663 values = singleton(v);
1670 public String toString()
1672 return "{" + k + "=" + v + "}";
1674 } // class SingletonMap
1677 * Sort a list according to the natural ordering of its elements. The list
1678 * must be modifiable, but can be of fixed size. The sort algorithm is
1679 * precisely that used by Arrays.sort(Object[]), which offers guaranteed
1680 * nlog(n) performance. This implementation dumps the list into an array,
1681 * sorts the array, and then iterates over the list setting each element from
1684 * @param l the List to sort
1685 * @throws ClassCastException if some items are not mutually comparable
1686 * @throws UnsupportedOperationException if the List is not modifiable
1687 * @throws NullPointerException if some element is null
1688 * @see Arrays#sort(Object[])
1690 public static void sort(List l)
1696 * Sort a list according to a specified Comparator. The list must be
1697 * modifiable, but can be of fixed size. The sort algorithm is precisely that
1698 * used by Arrays.sort(Object[], Comparator), which offers guaranteed
1699 * nlog(n) performance. This implementation dumps the list into an array,
1700 * sorts the array, and then iterates over the list setting each element from
1703 * @param l the List to sort
1704 * @param c the Comparator specifying the ordering for the elements, or
1705 * null for natural ordering
1706 * @throws ClassCastException if c will not compare some pair of items
1707 * @throws UnsupportedOperationException if the List is not modifiable
1708 * @throws NullPointerException if null is compared by natural ordering
1709 * (only possible when c is null)
1710 * @see Arrays#sort(Object[], Comparator)
1712 public static void sort(List l, Comparator c)
1714 Object[] a = l.toArray();
1716 ListIterator i = l.listIterator();
1717 for (int pos = 0, alen = a.length; pos < alen; pos++)
1725 * Swaps the elements at the specified positions within the list. Equal
1726 * positions have no effect.
1728 * @param l the list to work on
1729 * @param i the first index to swap
1730 * @param j the second index
1731 * @throws UnsupportedOperationException if list.set is not supported
1732 * @throws IndexOutOfBoundsException if either i or j is < 0 or >=
1736 public static void swap(List l, int i, int j)
1738 l.set(i, l.set(j, l.get(i)));
1743 * Returns a synchronized (thread-safe) collection wrapper backed by the
1744 * given collection. Notice that element access through the iterators
1745 * is thread-safe, but if the collection can be structurally modified
1746 * (adding or removing elements) then you should synchronize around the
1747 * iteration to avoid non-deterministic behavior:<br>
1749 * Collection c = Collections.synchronizedCollection(new Collection(...));
1753 * Iterator i = c.iterator();
1754 * while (i.hasNext())
1759 * Since the collection might be a List or a Set, and those have incompatible
1760 * equals and hashCode requirements, this relies on Object's implementation
1761 * rather than passing those calls on to the wrapped collection. The returned
1762 * Collection implements Serializable, but can only be serialized if
1763 * the collection it wraps is likewise Serializable.
1765 * @param c the collection to wrap
1766 * @return a synchronized view of the collection
1769 public static Collection synchronizedCollection(Collection c)
1771 return new SynchronizedCollection(c);
1775 * The implementation of {@link #synchronizedCollection(Collection)}. This
1776 * class name is required for compatibility with Sun's JDK serializability.
1777 * Package visible, so that collections such as the one for
1778 * Hashtable.values() can specify which object to synchronize on.
1780 * @author Eric Blake <ebb9@email.byu.edu>
1782 static class SynchronizedCollection
1783 implements Collection, Serializable
1786 * Compatible with JDK 1.4.
1788 private static final long serialVersionUID = 3053995032091335093L;
1791 * The wrapped collection. Package visible for use by subclasses.
1792 * @serial the real collection
1797 * The object to synchronize on. When an instance is created via public
1798 * methods, it will be this; but other uses like SynchronizedMap.values()
1799 * must specify another mutex. Package visible for use by subclasses.
1805 * Wrap a given collection.
1806 * @param c the collection to wrap
1807 * @throws NullPointerException if c is null
1809 SynchronizedCollection(Collection c)
1814 throw new NullPointerException();
1818 * Called only by trusted code to specify the mutex as well as the
1820 * @param sync the mutex
1821 * @param c the collection
1823 SynchronizedCollection(Object sync, Collection c)
1829 public boolean add(Object o)
1831 synchronized (mutex)
1837 public boolean addAll(Collection col)
1839 synchronized (mutex)
1841 return c.addAll(col);
1847 synchronized (mutex)
1853 public boolean contains(Object o)
1855 synchronized (mutex)
1857 return c.contains(o);
1861 public boolean containsAll(Collection c1)
1863 synchronized (mutex)
1865 return c.containsAll(c1);
1869 public boolean isEmpty()
1871 synchronized (mutex)
1877 public Iterator iterator()
1879 synchronized (mutex)
1881 return new SynchronizedIterator(mutex, c.iterator());
1885 public boolean remove(Object o)
1887 synchronized (mutex)
1893 public boolean removeAll(Collection col)
1895 synchronized (mutex)
1897 return c.removeAll(col);
1901 public boolean retainAll(Collection col)
1903 synchronized (mutex)
1905 return c.retainAll(col);
1911 synchronized (mutex)
1917 public Object[] toArray()
1919 synchronized (mutex)
1925 public Object[] toArray(Object[] a)
1927 synchronized (mutex)
1929 return c.toArray(a);
1933 public String toString()
1935 synchronized (mutex)
1937 return c.toString();
1940 } // class SynchronizedCollection
1943 * The implementation of the various iterator methods in the
1944 * synchronized classes. These iterators must "sync" on the same object
1945 * as the collection they iterate over.
1947 * @author Eric Blake <ebb9@email.byu.edu>
1949 private static class SynchronizedIterator implements Iterator
1952 * The object to synchronize on. Package visible for use by subclass.
1957 * The wrapped iterator.
1959 private final Iterator i;
1962 * Only trusted code creates a wrapper, with the specified sync.
1963 * @param sync the mutex
1964 * @param i the wrapped iterator
1966 SynchronizedIterator(Object sync, Iterator i)
1972 public Object next()
1974 synchronized (mutex)
1980 public boolean hasNext()
1982 synchronized (mutex)
1988 public void remove()
1990 synchronized (mutex)
1995 } // class SynchronizedIterator
1998 * Returns a synchronized (thread-safe) list wrapper backed by the
1999 * given list. Notice that element access through the iterators
2000 * is thread-safe, but if the list can be structurally modified
2001 * (adding or removing elements) then you should synchronize around the
2002 * iteration to avoid non-deterministic behavior:<br>
2004 * List l = Collections.synchronizedList(new List(...));
2008 * Iterator i = l.iterator();
2009 * while (i.hasNext())
2014 * The returned List implements Serializable, but can only be serialized if
2015 * the list it wraps is likewise Serializable. In addition, if the wrapped
2016 * list implements RandomAccess, this does too.
2018 * @param l the list to wrap
2019 * @return a synchronized view of the list
2023 public static List synchronizedList(List l)
2025 if (l instanceof RandomAccess)
2026 return new SynchronizedRandomAccessList(l);
2027 return new SynchronizedList(l);
2031 * The implementation of {@link #synchronizedList(List)} for sequential
2032 * lists. This class name is required for compatibility with Sun's JDK
2033 * serializability. Package visible, so that lists such as Vector.subList()
2034 * can specify which object to synchronize on.
2036 * @author Eric Blake <ebb9@email.byu.edu>
2038 static class SynchronizedList extends SynchronizedCollection
2042 * Compatible with JDK 1.4.
2044 private static final long serialVersionUID = -7754090372962971524L;
2047 * The wrapped list; stored both here and in the superclass to avoid
2048 * excessive casting. Package visible for use by subclass.
2049 * @serial the wrapped list
2054 * Wrap a given list.
2055 * @param l the list to wrap
2056 * @throws NullPointerException if l is null
2058 SynchronizedList(List l)
2065 * Called only by trusted code to specify the mutex as well as the list.
2066 * @param sync the mutex
2069 SynchronizedList(Object sync, List l)
2075 public void add(int index, Object o)
2077 synchronized (mutex)
2083 public boolean addAll(int index, Collection c)
2085 synchronized (mutex)
2087 return list.addAll(index, c);
2091 public boolean equals(Object o)
2093 synchronized (mutex)
2095 return list.equals(o);
2099 public Object get(int index)
2101 synchronized (mutex)
2103 return list.get(index);
2107 public int hashCode()
2109 synchronized (mutex)
2111 return list.hashCode();
2115 public int indexOf(Object o)
2117 synchronized (mutex)
2119 return list.indexOf(o);
2123 public int lastIndexOf(Object o)
2125 synchronized (mutex)
2127 return list.lastIndexOf(o);
2131 public ListIterator listIterator()
2133 synchronized (mutex)
2135 return new SynchronizedListIterator(mutex, list.listIterator());
2139 public ListIterator listIterator(int index)
2141 synchronized (mutex)
2143 return new SynchronizedListIterator(mutex, list.listIterator(index));
2147 public Object remove(int index)
2149 synchronized (mutex)
2151 return list.remove(index);
2155 public Object set(int index, Object o)
2157 synchronized (mutex)
2159 return list.set(index, o);
2163 public List subList(int fromIndex, int toIndex)
2165 synchronized (mutex)
2167 return new SynchronizedList(mutex, list.subList(fromIndex, toIndex));
2170 } // class SynchronizedList
2173 * The implementation of {@link #synchronizedList(List)} for random-access
2174 * lists. This class name is required for compatibility with Sun's JDK
2177 * @author Eric Blake <ebb9@email.byu.edu>
2179 private static final class SynchronizedRandomAccessList
2180 extends SynchronizedList implements RandomAccess
2183 * Compatible with JDK 1.4.
2185 private static final long serialVersionUID = 1530674583602358482L;
2188 * Wrap a given list.
2189 * @param l the list to wrap
2190 * @throws NullPointerException if l is null
2192 SynchronizedRandomAccessList(List l)
2198 * Called only by trusted code to specify the mutex as well as the
2200 * @param sync the mutex
2203 SynchronizedRandomAccessList(Object sync, List l)
2208 public List subList(int fromIndex, int toIndex)
2210 synchronized (mutex)
2212 return new SynchronizedRandomAccessList(mutex,
2213 list.subList(fromIndex,
2217 } // class SynchronizedRandomAccessList
2220 * The implementation of {@link SynchronizedList#listIterator()}. This
2221 * iterator must "sync" on the same object as the list it iterates over.
2223 * @author Eric Blake <ebb9@email.byu.edu>
2225 private static final class SynchronizedListIterator
2226 extends SynchronizedIterator implements ListIterator
2229 * The wrapped iterator, stored both here and in the superclass to
2230 * avoid excessive casting.
2232 private final ListIterator li;
2235 * Only trusted code creates a wrapper, with the specified sync.
2236 * @param sync the mutex
2237 * @param li the wrapped iterator
2239 SynchronizedListIterator(Object sync, ListIterator li)
2245 public void add(Object o)
2247 synchronized (mutex)
2252 public boolean hasPrevious()
2254 synchronized (mutex)
2256 return li.hasPrevious();
2260 public int nextIndex()
2262 synchronized (mutex)
2264 return li.nextIndex();
2268 public Object previous()
2270 synchronized (mutex)
2272 return li.previous();
2276 public int previousIndex()
2278 synchronized (mutex)
2280 return li.previousIndex();
2284 public void set(Object o)
2286 synchronized (mutex)
2291 } // class SynchronizedListIterator
2294 * Returns a synchronized (thread-safe) map wrapper backed by the given
2295 * map. Notice that element access through the collection views and their
2296 * iterators are thread-safe, but if the map can be structurally modified
2297 * (adding or removing elements) then you should synchronize around the
2298 * iteration to avoid non-deterministic behavior:<br>
2300 * Map m = Collections.synchronizedMap(new Map(...));
2302 * Set s = m.keySet(); // safe outside a synchronized block
2303 * synchronized (m) // synch on m, not s
2305 * Iterator i = s.iterator();
2306 * while (i.hasNext())
2311 * The returned Map implements Serializable, but can only be serialized if
2312 * the map it wraps is likewise Serializable.
2314 * @param m the map to wrap
2315 * @return a synchronized view of the map
2318 public static Map synchronizedMap(Map m)
2320 return new SynchronizedMap(m);
2324 * The implementation of {@link #synchronizedMap(Map)}. This
2325 * class name is required for compatibility with Sun's JDK serializability.
2327 * @author Eric Blake <ebb9@email.byu.edu>
2329 private static class SynchronizedMap implements Map, Serializable
2332 * Compatible with JDK 1.4.
2334 private static final long serialVersionUID = 1978198479659022715L;
2338 * @serial the real map
2340 private final Map m;
2343 * The object to synchronize on. When an instance is created via public
2344 * methods, it will be this; but other uses like
2345 * SynchronizedSortedMap.subMap() must specify another mutex. Package
2346 * visible for use by subclass.
2352 * Cache the entry set.
2354 private transient Set entries;
2357 * Cache the key set.
2359 private transient Set keys;
2362 * Cache the value collection.
2364 private transient Collection values;
2368 * @param m the map to wrap
2369 * @throws NullPointerException if m is null
2371 SynchronizedMap(Map m)
2376 throw new NullPointerException();
2380 * Called only by trusted code to specify the mutex as well as the map.
2381 * @param sync the mutex
2384 SynchronizedMap(Object sync, Map m)
2392 synchronized (mutex)
2398 public boolean containsKey(Object key)
2400 synchronized (mutex)
2402 return m.containsKey(key);
2406 public boolean containsValue(Object value)
2408 synchronized (mutex)
2410 return m.containsValue(value);
2414 // This is one of the ickiest cases of nesting I've ever seen. It just
2415 // means "return a SynchronizedSet, except that the iterator() method
2416 // returns an SynchronizedIterator whose next() method returns a
2417 // synchronized wrapper around its normal return value".
2418 public Set entrySet()
2420 // Define this here to spare some nesting.
2421 class SynchronizedMapEntry implements Map.Entry
2424 SynchronizedMapEntry(Object o)
2428 public boolean equals(Object o)
2430 synchronized (mutex)
2435 public Object getKey()
2437 synchronized (mutex)
2442 public Object getValue()
2444 synchronized (mutex)
2446 return e.getValue();
2449 public int hashCode()
2451 synchronized (mutex)
2453 return e.hashCode();
2456 public Object setValue(Object value)
2458 synchronized (mutex)
2460 return e.setValue(value);
2463 public String toString()
2465 synchronized (mutex)
2467 return e.toString();
2470 } // class SynchronizedMapEntry
2472 // Now the actual code.
2473 if (entries == null)
2474 synchronized (mutex)
2476 entries = new SynchronizedSet(mutex, m.entrySet())
2478 public Iterator iterator()
2480 synchronized (super.mutex)
2482 return new SynchronizedIterator(super.mutex, c.iterator())
2484 public Object next()
2486 synchronized (super.mutex)
2488 return new SynchronizedMapEntry(super.next());
2499 public boolean equals(Object o)
2501 synchronized (mutex)
2507 public Object get(Object key)
2509 synchronized (mutex)
2515 public int hashCode()
2517 synchronized (mutex)
2519 return m.hashCode();
2523 public boolean isEmpty()
2525 synchronized (mutex)
2534 synchronized (mutex)
2536 keys = new SynchronizedSet(mutex, m.keySet());
2541 public Object put(Object key, Object value)
2543 synchronized (mutex)
2545 return m.put(key, value);
2549 public void putAll(Map map)
2551 synchronized (mutex)
2557 public Object remove(Object o)
2559 synchronized (mutex)
2567 synchronized (mutex)
2573 public String toString()
2575 synchronized (mutex)
2577 return m.toString();
2581 public Collection values()
2584 synchronized (mutex)
2586 values = new SynchronizedCollection(mutex, m.values());
2590 } // class SynchronizedMap
2593 * Returns a synchronized (thread-safe) set wrapper backed by the given
2594 * set. Notice that element access through the iterator is thread-safe, but
2595 * if the set can be structurally modified (adding or removing elements)
2596 * then you should synchronize around the iteration to avoid
2597 * non-deterministic behavior:<br>
2599 * Set s = Collections.synchronizedSet(new Set(...));
2603 * Iterator i = s.iterator();
2604 * while (i.hasNext())
2609 * The returned Set implements Serializable, but can only be serialized if
2610 * the set it wraps is likewise Serializable.
2612 * @param s the set to wrap
2613 * @return a synchronized view of the set
2616 public static Set synchronizedSet(Set s)
2618 return new SynchronizedSet(s);
2622 * The implementation of {@link #synchronizedSet(Set)}. This class
2623 * name is required for compatibility with Sun's JDK serializability.
2624 * Package visible, so that sets such as Hashtable.keySet()
2625 * can specify which object to synchronize on.
2627 * @author Eric Blake <ebb9@email.byu.edu>
2629 static class SynchronizedSet extends SynchronizedCollection
2633 * Compatible with JDK 1.4.
2635 private static final long serialVersionUID = 487447009682186044L;
2639 * @param s the set to wrap
2640 * @throws NullPointerException if s is null
2642 SynchronizedSet(Set s)
2648 * Called only by trusted code to specify the mutex as well as the set.
2649 * @param sync the mutex
2652 SynchronizedSet(Object sync, Set s)
2657 public boolean equals(Object o)
2659 synchronized (mutex)
2665 public int hashCode()
2667 synchronized (mutex)
2669 return c.hashCode();
2672 } // class SynchronizedSet
2675 * Returns a synchronized (thread-safe) sorted map wrapper backed by the
2676 * given map. Notice that element access through the collection views,
2677 * subviews, and their iterators are thread-safe, but if the map can be
2678 * structurally modified (adding or removing elements) then you should
2679 * synchronize around the iteration to avoid non-deterministic behavior:<br>
2681 * SortedMap m = Collections.synchronizedSortedMap(new SortedMap(...));
2683 * Set s = m.keySet(); // safe outside a synchronized block
2684 * SortedMap m2 = m.headMap(foo); // safe outside a synchronized block
2685 * Set s2 = m2.keySet(); // safe outside a synchronized block
2686 * synchronized (m) // synch on m, not m2, s or s2
2688 * Iterator i = s.iterator();
2689 * while (i.hasNext())
2691 * i = s2.iterator();
2692 * while (i.hasNext())
2697 * The returned SortedMap implements Serializable, but can only be
2698 * serialized if the map it wraps is likewise Serializable.
2700 * @param m the sorted map to wrap
2701 * @return a synchronized view of the sorted map
2704 public static SortedMap synchronizedSortedMap(SortedMap m)
2706 return new SynchronizedSortedMap(m);
2710 * The implementation of {@link #synchronizedSortedMap(SortedMap)}. This
2711 * class name is required for compatibility with Sun's JDK serializability.
2713 * @author Eric Blake <ebb9@email.byu.edu>
2715 private static final class SynchronizedSortedMap extends SynchronizedMap
2716 implements SortedMap
2719 * Compatible with JDK 1.4.
2721 private static final long serialVersionUID = -8798146769416483793L;
2724 * The wrapped map; stored both here and in the superclass to avoid
2725 * excessive casting.
2726 * @serial the wrapped map
2728 private final SortedMap sm;
2732 * @param sm the map to wrap
2733 * @throws NullPointerException if sm is null
2735 SynchronizedSortedMap(SortedMap sm)
2742 * Called only by trusted code to specify the mutex as well as the map.
2743 * @param sync the mutex
2746 SynchronizedSortedMap(Object sync, SortedMap sm)
2752 public Comparator comparator()
2754 synchronized (mutex)
2756 return sm.comparator();
2760 public Object firstKey()
2762 synchronized (mutex)
2764 return sm.firstKey();
2768 public SortedMap headMap(Object toKey)
2770 synchronized (mutex)
2772 return new SynchronizedSortedMap(mutex, sm.headMap(toKey));
2776 public Object lastKey()
2778 synchronized (mutex)
2780 return sm.lastKey();
2784 public SortedMap subMap(Object fromKey, Object toKey)
2786 synchronized (mutex)
2788 return new SynchronizedSortedMap(mutex, sm.subMap(fromKey, toKey));
2792 public SortedMap tailMap(Object fromKey)
2794 synchronized (mutex)
2796 return new SynchronizedSortedMap(mutex, sm.tailMap(fromKey));
2799 } // class SynchronizedSortedMap
2802 * Returns a synchronized (thread-safe) sorted set wrapper backed by the
2803 * given set. Notice that element access through the iterator and through
2804 * subviews are thread-safe, but if the set can be structurally modified
2805 * (adding or removing elements) then you should synchronize around the
2806 * iteration to avoid non-deterministic behavior:<br>
2808 * SortedSet s = Collections.synchronizedSortedSet(new SortedSet(...));
2810 * SortedSet s2 = s.headSet(foo); // safe outside a synchronized block
2811 * synchronized (s) // synch on s, not s2
2813 * Iterator i = s2.iterator();
2814 * while (i.hasNext())
2819 * The returned SortedSet implements Serializable, but can only be
2820 * serialized if the set it wraps is likewise Serializable.
2822 * @param s the sorted set to wrap
2823 * @return a synchronized view of the sorted set
2826 public static SortedSet synchronizedSortedSet(SortedSet s)
2828 return new SynchronizedSortedSet(s);
2832 * The implementation of {@link #synchronizedSortedSet(SortedSet)}. This
2833 * class name is required for compatibility with Sun's JDK serializability.
2835 * @author Eric Blake <ebb9@email.byu.edu>
2837 private static final class SynchronizedSortedSet extends SynchronizedSet
2838 implements SortedSet
2841 * Compatible with JDK 1.4.
2843 private static final long serialVersionUID = 8695801310862127406L;
2846 * The wrapped set; stored both here and in the superclass to avoid
2847 * excessive casting.
2848 * @serial the wrapped set
2850 private final SortedSet ss;
2854 * @param ss the set to wrap
2855 * @throws NullPointerException if ss is null
2857 SynchronizedSortedSet(SortedSet ss)
2864 * Called only by trusted code to specify the mutex as well as the set.
2865 * @param sync the mutex
2868 SynchronizedSortedSet(Object sync, SortedSet ss)
2874 public Comparator comparator()
2876 synchronized (mutex)
2878 return ss.comparator();
2882 public Object first()
2884 synchronized (mutex)
2890 public SortedSet headSet(Object toElement)
2892 synchronized (mutex)
2894 return new SynchronizedSortedSet(mutex, ss.headSet(toElement));
2898 public Object last()
2900 synchronized (mutex)
2906 public SortedSet subSet(Object fromElement, Object toElement)
2908 synchronized (mutex)
2910 return new SynchronizedSortedSet(mutex,
2911 ss.subSet(fromElement, toElement));
2915 public SortedSet tailSet(Object fromElement)
2917 synchronized (mutex)
2919 return new SynchronizedSortedSet(mutex, ss.tailSet(fromElement));
2922 } // class SynchronizedSortedSet
2926 * Returns an unmodifiable view of the given collection. This allows
2927 * "read-only" access, although changes in the backing collection show up
2928 * in this view. Attempts to modify the collection directly or via iterators
2929 * will fail with {@link UnsupportedOperationException}.
2932 * Since the collection might be a List or a Set, and those have incompatible
2933 * equals and hashCode requirements, this relies on Object's implementation
2934 * rather than passing those calls on to the wrapped collection. The returned
2935 * Collection implements Serializable, but can only be serialized if
2936 * the collection it wraps is likewise Serializable.
2938 * @param c the collection to wrap
2939 * @return a read-only view of the collection
2942 public static Collection unmodifiableCollection(Collection c)
2944 return new UnmodifiableCollection(c);
2948 * The implementation of {@link #unmodifiableCollection(Collection)}. This
2949 * class name is required for compatibility with Sun's JDK serializability.
2951 * @author Eric Blake <ebb9@email.byu.edu>
2953 private static class UnmodifiableCollection
2954 implements Collection, Serializable
2957 * Compatible with JDK 1.4.
2959 private static final long serialVersionUID = 1820017752578914078L;
2962 * The wrapped collection. Package visible for use by subclasses.
2963 * @serial the real collection
2968 * Wrap a given collection.
2969 * @param c the collection to wrap
2970 * @throws NullPointerException if c is null
2972 UnmodifiableCollection(Collection c)
2976 throw new NullPointerException();
2979 public boolean add(Object o)
2981 throw new UnsupportedOperationException();
2984 public boolean addAll(Collection c)
2986 throw new UnsupportedOperationException();
2991 throw new UnsupportedOperationException();
2994 public boolean contains(Object o)
2996 return c.contains(o);
2999 public boolean containsAll(Collection c1)
3001 return c.containsAll(c1);
3004 public boolean isEmpty()
3009 public Iterator iterator()
3011 return new UnmodifiableIterator(c.iterator());
3014 public boolean remove(Object o)
3016 throw new UnsupportedOperationException();
3019 public boolean removeAll(Collection c)
3021 throw new UnsupportedOperationException();
3024 public boolean retainAll(Collection c)
3026 throw new UnsupportedOperationException();
3034 public Object[] toArray()
3039 public Object[] toArray(Object[] a)
3041 return c.toArray(a);
3044 public String toString()
3046 return c.toString();
3048 } // class UnmodifiableCollection
3051 * The implementation of the various iterator methods in the
3052 * unmodifiable classes.
3054 * @author Eric Blake <ebb9@email.byu.edu>
3056 private static class UnmodifiableIterator implements Iterator
3059 * The wrapped iterator.
3061 private final Iterator i;
3064 * Only trusted code creates a wrapper.
3065 * @param i the wrapped iterator
3067 UnmodifiableIterator(Iterator i)
3072 public Object next()
3077 public boolean hasNext()
3082 public void remove()
3084 throw new UnsupportedOperationException();
3086 } // class UnmodifiableIterator
3089 * Returns an unmodifiable view of the given list. This allows
3090 * "read-only" access, although changes in the backing list show up
3091 * in this view. Attempts to modify the list directly, via iterators, or
3092 * via sublists, will fail with {@link UnsupportedOperationException}.
3095 * The returned List implements Serializable, but can only be serialized if
3096 * the list it wraps is likewise Serializable. In addition, if the wrapped
3097 * list implements RandomAccess, this does too.
3099 * @param l the list to wrap
3100 * @return a read-only view of the list
3104 public static List unmodifiableList(List l)
3106 if (l instanceof RandomAccess)
3107 return new UnmodifiableRandomAccessList(l);
3108 return new UnmodifiableList(l);
3112 * The implementation of {@link #unmodifiableList(List)} for sequential
3113 * lists. This class name is required for compatibility with Sun's JDK
3116 * @author Eric Blake <ebb9@email.byu.edu>
3118 private static class UnmodifiableList extends UnmodifiableCollection
3122 * Compatible with JDK 1.4.
3124 private static final long serialVersionUID = -283967356065247728L;
3128 * The wrapped list; stored both here and in the superclass to avoid
3129 * excessive casting. Package visible for use by subclass.
3130 * @serial the wrapped list
3135 * Wrap a given list.
3136 * @param l the list to wrap
3137 * @throws NullPointerException if l is null
3139 UnmodifiableList(List l)
3145 public void add(int index, Object o)
3147 throw new UnsupportedOperationException();
3150 public boolean addAll(int index, Collection c)
3152 throw new UnsupportedOperationException();
3155 public boolean equals(Object o)
3157 return list.equals(o);
3160 public Object get(int index)
3162 return list.get(index);
3165 public int hashCode()
3167 return list.hashCode();
3170 public int indexOf(Object o)
3172 return list.indexOf(o);
3175 public int lastIndexOf(Object o)
3177 return list.lastIndexOf(o);
3180 public ListIterator listIterator()
3182 return new UnmodifiableListIterator(list.listIterator());
3185 public ListIterator listIterator(int index)
3187 return new UnmodifiableListIterator(list.listIterator(index));
3190 public Object remove(int index)
3192 throw new UnsupportedOperationException();
3195 public Object set(int index, Object o)
3197 throw new UnsupportedOperationException();
3200 public List subList(int fromIndex, int toIndex)
3202 return unmodifiableList(list.subList(fromIndex, toIndex));
3204 } // class UnmodifiableList
3207 * The implementation of {@link #unmodifiableList(List)} for random-access
3208 * lists. This class name is required for compatibility with Sun's JDK
3211 * @author Eric Blake <ebb9@email.byu.edu>
3213 private static final class UnmodifiableRandomAccessList
3214 extends UnmodifiableList implements RandomAccess
3217 * Compatible with JDK 1.4.
3219 private static final long serialVersionUID = -2542308836966382001L;
3222 * Wrap a given list.
3223 * @param l the list to wrap
3224 * @throws NullPointerException if l is null
3226 UnmodifiableRandomAccessList(List l)
3230 } // class UnmodifiableRandomAccessList
3233 * The implementation of {@link UnmodifiableList#listIterator()}.
3235 * @author Eric Blake <ebb9@email.byu.edu>
3237 private static final class UnmodifiableListIterator
3238 extends UnmodifiableIterator implements ListIterator
3241 * The wrapped iterator, stored both here and in the superclass to
3242 * avoid excessive casting.
3244 private final ListIterator li;
3247 * Only trusted code creates a wrapper.
3248 * @param li the wrapped iterator
3250 UnmodifiableListIterator(ListIterator li)
3256 public void add(Object o)
3258 throw new UnsupportedOperationException();
3261 public boolean hasPrevious()
3263 return li.hasPrevious();
3266 public int nextIndex()
3268 return li.nextIndex();
3271 public Object previous()
3273 return li.previous();
3276 public int previousIndex()
3278 return li.previousIndex();
3281 public void set(Object o)
3283 throw new UnsupportedOperationException();
3285 } // class UnmodifiableListIterator
3288 * Returns an unmodifiable view of the given map. This allows "read-only"
3289 * access, although changes in the backing map show up in this view.
3290 * Attempts to modify the map directly, or via collection views or their
3291 * iterators will fail with {@link UnsupportedOperationException}.
3294 * The returned Map implements Serializable, but can only be serialized if
3295 * the map it wraps is likewise Serializable.
3297 * @param m the map to wrap
3298 * @return a read-only view of the map
3301 public static Map unmodifiableMap(Map m)
3303 return new UnmodifiableMap(m);
3307 * The implementation of {@link #unmodifiableMap(Map)}. This
3308 * class name is required for compatibility with Sun's JDK serializability.
3310 * @author Eric Blake <ebb9@email.byu.edu>
3312 private static class UnmodifiableMap implements Map, Serializable
3315 * Compatible with JDK 1.4.
3317 private static final long serialVersionUID = -1034234728574286014L;
3321 * @serial the real map
3323 private final Map m;
3326 * Cache the entry set.
3328 private transient Set entries;
3331 * Cache the key set.
3333 private transient Set keys;
3336 * Cache the value collection.
3338 private transient Collection values;
3342 * @param m the map to wrap
3343 * @throws NullPointerException if m is null
3345 UnmodifiableMap(Map m)
3349 throw new NullPointerException();
3354 throw new UnsupportedOperationException();
3357 public boolean containsKey(Object key)
3359 return m.containsKey(key);
3362 public boolean containsValue(Object value)
3364 return m.containsValue(value);
3367 public Set entrySet()
3369 if (entries == null)
3370 entries = new UnmodifiableEntrySet(m.entrySet());
3375 * The implementation of {@link UnmodifiableMap#entrySet()}. This class
3376 * name is required for compatibility with Sun's JDK serializability.
3378 * @author Eric Blake <ebb9@email.byu.edu>
3380 private static final class UnmodifiableEntrySet extends UnmodifiableSet
3381 implements Serializable
3384 * Compatible with JDK 1.4.
3386 private static final long serialVersionUID = 7854390611657943733L;
3390 * @param s the set to wrap
3392 UnmodifiableEntrySet(Set s)
3397 // The iterator must return unmodifiable map entries.
3398 public Iterator iterator()
3400 return new UnmodifiableIterator(c.iterator())
3402 public Object next()
3404 final Map.Entry e = (Map.Entry) super.next();
3405 return new Map.Entry()
3407 public boolean equals(Object o)
3411 public Object getKey()
3415 public Object getValue()
3417 return e.getValue();
3419 public int hashCode()
3421 return e.hashCode();
3423 public Object setValue(Object value)
3425 throw new UnsupportedOperationException();
3427 public String toString()
3429 return e.toString();
3435 } // class UnmodifiableEntrySet
3437 public boolean equals(Object o)
3442 public Object get(Object key)
3447 public Object put(Object key, Object value)
3449 throw new UnsupportedOperationException();
3452 public int hashCode()
3454 return m.hashCode();
3457 public boolean isEmpty()
3465 keys = new UnmodifiableSet(m.keySet());
3469 public void putAll(Map m)
3471 throw new UnsupportedOperationException();
3474 public Object remove(Object o)
3476 throw new UnsupportedOperationException();
3484 public String toString()
3486 return m.toString();
3489 public Collection values()
3492 values = new UnmodifiableCollection(m.values());
3495 } // class UnmodifiableMap
3498 * Returns an unmodifiable view of the given set. This allows
3499 * "read-only" access, although changes in the backing set show up
3500 * in this view. Attempts to modify the set directly or via iterators
3501 * will fail with {@link UnsupportedOperationException}.
3504 * The returned Set implements Serializable, but can only be serialized if
3505 * the set it wraps is likewise Serializable.
3507 * @param s the set to wrap
3508 * @return a read-only view of the set
3511 public static Set unmodifiableSet(Set s)
3513 return new UnmodifiableSet(s);
3517 * The implementation of {@link #unmodifiableSet(Set)}. This class
3518 * name is required for compatibility with Sun's JDK serializability.
3520 * @author Eric Blake <ebb9@email.byu.edu>
3522 private static class UnmodifiableSet extends UnmodifiableCollection
3526 * Compatible with JDK 1.4.
3528 private static final long serialVersionUID = -9215047833775013803L;
3532 * @param s the set to wrap
3533 * @throws NullPointerException if s is null
3535 UnmodifiableSet(Set s)
3540 public boolean equals(Object o)
3545 public int hashCode()
3547 return c.hashCode();
3549 } // class UnmodifiableSet
3552 * Returns an unmodifiable view of the given sorted map. This allows
3553 * "read-only" access, although changes in the backing map show up in this
3554 * view. Attempts to modify the map directly, via subviews, via collection
3555 * views, or iterators, will fail with {@link UnsupportedOperationException}.
3558 * The returned SortedMap implements Serializable, but can only be
3559 * serialized if the map it wraps is likewise Serializable.
3561 * @param m the map to wrap
3562 * @return a read-only view of the map
3565 public static SortedMap unmodifiableSortedMap(SortedMap m)
3567 return new UnmodifiableSortedMap(m);
3571 * The implementation of {@link #unmodifiableSortedMap(SortedMap)}. This
3572 * class name is required for compatibility with Sun's JDK serializability.
3574 * @author Eric Blake <ebb9@email.byu.edu>
3576 private static class UnmodifiableSortedMap extends UnmodifiableMap
3577 implements SortedMap
3580 * Compatible with JDK 1.4.
3582 private static final long serialVersionUID = -8806743815996713206L;
3585 * The wrapped map; stored both here and in the superclass to avoid
3586 * excessive casting.
3587 * @serial the wrapped map
3589 private final SortedMap sm;
3593 * @param sm the map to wrap
3594 * @throws NullPointerException if sm is null
3596 UnmodifiableSortedMap(SortedMap sm)
3602 public Comparator comparator()
3604 return sm.comparator();
3607 public Object firstKey()
3609 return sm.firstKey();
3612 public SortedMap headMap(Object toKey)
3614 return new UnmodifiableSortedMap(sm.headMap(toKey));
3617 public Object lastKey()
3619 return sm.lastKey();
3622 public SortedMap subMap(Object fromKey, Object toKey)
3624 return new UnmodifiableSortedMap(sm.subMap(fromKey, toKey));
3627 public SortedMap tailMap(Object fromKey)
3629 return new UnmodifiableSortedMap(sm.tailMap(fromKey));
3631 } // class UnmodifiableSortedMap
3634 * Returns an unmodifiable view of the given sorted set. This allows
3635 * "read-only" access, although changes in the backing set show up
3636 * in this view. Attempts to modify the set directly, via subsets, or via
3637 * iterators, will fail with {@link UnsupportedOperationException}.
3640 * The returns SortedSet implements Serializable, but can only be
3641 * serialized if the set it wraps is likewise Serializable.
3643 * @param s the set to wrap
3644 * @return a read-only view of the set
3647 public static SortedSet unmodifiableSortedSet(SortedSet s)
3649 return new UnmodifiableSortedSet(s);
3653 * The implementation of {@link #synchronizedSortedMap(SortedMap)}. This
3654 * class name is required for compatibility with Sun's JDK serializability.
3656 * @author Eric Blake <ebb9@email.byu.edu>
3658 private static class UnmodifiableSortedSet extends UnmodifiableSet
3659 implements SortedSet
3662 * Compatible with JDK 1.4.
3664 private static final long serialVersionUID = -4929149591599911165L;
3667 * The wrapped set; stored both here and in the superclass to avoid
3668 * excessive casting.
3669 * @serial the wrapped set
3671 private SortedSet ss;
3675 * @param ss the set to wrap
3676 * @throws NullPointerException if ss is null
3678 UnmodifiableSortedSet(SortedSet ss)
3684 public Comparator comparator()
3686 return ss.comparator();
3689 public Object first()
3694 public SortedSet headSet(Object toElement)
3696 return new UnmodifiableSortedSet(ss.headSet(toElement));
3699 public Object last()
3704 public SortedSet subSet(Object fromElement, Object toElement)
3706 return new UnmodifiableSortedSet(ss.subSet(fromElement, toElement));
3709 public SortedSet tailSet(Object fromElement)
3711 return new UnmodifiableSortedSet(ss.tailSet(fromElement));
3713 } // class UnmodifiableSortedSet
3714 } // class Collections