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();
579 pos
= (low
+ hi
) >> 1;
581 for ( ; i
!= pos
; i
++, itr
.next());
583 for ( ; i
!= pos
; i
--, itr
.previous());
584 final int d
= compare(key
, itr
.next(), c
);
590 // This gets the insertion point right on the last loop
598 pos
= (low
+ hi
) >> 1;
599 final int d
= compare(key
, l
.get(pos
), c
);
605 // This gets the insertion point right on the last loop
610 // If we failed to find it, we do the same whichever search we did.
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
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();
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()
658 public final Object
nextElement()
666 * Replace every element of a list with a given value. This method runs in
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
)
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() > 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
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
))
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() > 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
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
))
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
738 public static ArrayList
list(Enumeration e
)
740 ArrayList l
= new ArrayList();
741 while (e
.hasMoreElements())
742 l
.add(e
.nextElement());
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
)
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
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)
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
)
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
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)
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 < 0
845 * @see List#addAll(Collection)
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
875 * The repeated list element.
876 * @serial the list contents
878 private final Object element
;
881 * Constructs the list.
884 * @param o the object
885 * @throws IllegalArgumentException if n < 0
887 CopiesList(int n
, Object o
)
890 throw new IllegalArgumentException();
904 * The same element is returned.
906 public Object
get(int index
)
908 if (index
< 0 || index
>= n
)
909 throw new IndexOutOfBoundsException();
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
);
952 public Object
[] toArray()
954 Object
[] a
= new Object
[n
];
955 Arrays
.fill(a
, element
);
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("}");
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
985 * @throws IllegalArgumentException some other aspect of newval stops
986 * it being added to the list
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()))
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();
1013 int pos2
= l
.size();
1014 ListIterator i2
= l
.listIterator(pos2
);
1017 Object o
= i1
.next();
1018 i1
.set(i2
.previous());
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
1036 public static Comparator
reverseOrder()
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.
1068 * Compare two objects in reverse natural order.
1070 * @param a the first object
1071 * @param b the second object
1072 * @return <, ==, or > 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.
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>.
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
1110 public static void rotate(List list
, int distance
)
1112 int size
= list
.size();
1119 if (isSequential(list
))
1122 reverse(list
.subList(0, distance
));
1123 reverse(list
.subList(distance
, size
));
1127 // Determine the least common multiple of distance and size, as there
1128 // are (distance / LCM) loops to cycle through.
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.
1143 Object o
= list
.get(lcm
);
1144 for (int i
= lcm
+ distance
; i
!= lcm
; i
= (i
+ distance
) % size
)
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)).
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
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)).
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.
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
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.
1236 a
[swap
] = i
.previous();
1239 o
= l
.set(swap
, i
.previous());
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
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
)
1290 * The size: always 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()
1311 public Object
next()
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();
1347 if (! equals(i
.next(), element
))
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
};
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
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
)
1422 * The size: always 1!
1430 * Only index 0 is valid.
1432 public Object
get(int index
)
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();
1457 if (! equals(i
.next(), element
))
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))
1493 if (from
== 0 && to
== 1)
1496 throw new IllegalArgumentException();
1497 throw new IndexOutOfBoundsException();
1501 * Returning an array is simple.
1503 public Object
[] toArray()
1505 return new Object
[] {element
};
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
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;
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
)
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();
1590 // The remaining methods are optional, but provide a performance
1591 // advantage by not allocating unnecessary iterators in AbstractMap.
1595 public boolean containsKey(Object key
)
1597 return equals(key
, k
);
1603 public boolean containsValue(Object value
)
1605 return equals(value
, v
);
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.
1630 keys
= singleton(k
);
1635 * The size: always 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()
1649 values
= singleton(v
);
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
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
)
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
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();
1702 ListIterator i
= l
.listIterator(a
.length
);
1703 for (int pos
= a
.length
; --pos
>= 0; )
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 < 0 or >=
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>
1735 * Collection c = Collections.synchronizedCollection(new Collection(...));
1739 * Iterator i = c.iterator();
1740 * while (i.hasNext())
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
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
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.
1791 * Wrap a given collection.
1792 * @param c the collection to wrap
1793 * @throws NullPointerException if c is null
1795 SynchronizedCollection(Collection c
)
1800 throw new NullPointerException();
1804 * Called only by trusted code to specify the mutex as well as the
1806 * @param sync the mutex
1807 * @param c the collection
1809 SynchronizedCollection(Object sync
, Collection c
)
1815 public boolean add(Object o
)
1817 synchronized (mutex
)
1823 public boolean addAll(Collection col
)
1825 synchronized (mutex
)
1827 return c
.addAll(col
);
1833 synchronized (mutex
)
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
)
1863 public Iterator
iterator()
1865 synchronized (mutex
)
1867 return new SynchronizedIterator(mutex
, c
.iterator());
1871 public boolean remove(Object o
)
1873 synchronized (mutex
)
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
);
1897 synchronized (mutex
)
1903 public Object
[] toArray()
1905 synchronized (mutex
)
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.
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
)
1958 public Object
next()
1960 synchronized (mutex
)
1966 public boolean hasNext()
1968 synchronized (mutex
)
1974 public void remove()
1976 synchronized (mutex
)
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>
1990 * List l = Collections.synchronizedList(new List(...));
1994 * Iterator i = l.iterator();
1995 * while (i.hasNext())
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
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
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
2040 * Wrap a given list.
2041 * @param l the list to wrap
2042 * @throws NullPointerException if l is null
2044 SynchronizedList(List l
)
2051 * Called only by trusted code to specify the mutex as well as the list.
2052 * @param sync the mutex
2055 SynchronizedList(Object sync
, List l
)
2061 public void add(int index
, Object o
)
2063 synchronized (mutex
)
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
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
)
2184 * Called only by trusted code to specify the mutex as well as the
2186 * @param sync the mutex
2189 SynchronizedRandomAccessList(Object sync
, List l
)
2194 public List
subList(int fromIndex
, int toIndex
)
2196 synchronized (mutex
)
2198 return new SynchronizedRandomAccessList(mutex
,
2199 list
.subList(fromIndex
,
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
)
2231 public void add(Object o
)
2233 synchronized (mutex
)
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
)
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>
2286 * Map m = Collections.synchronizedMap(new Map(...));
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())
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
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;
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.
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
;
2354 * @param m the map to wrap
2355 * @throws NullPointerException if m is null
2357 SynchronizedMap(Map m
)
2362 throw new NullPointerException();
2366 * Called only by trusted code to specify the mutex as well as the map.
2367 * @param sync the mutex
2370 SynchronizedMap(Object sync
, Map m
)
2378 synchronized (mutex
)
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
2410 SynchronizedMapEntry(Object o
)
2414 public boolean equals(Object o
)
2416 synchronized (mutex
)
2421 public Object
getKey()
2423 synchronized (mutex
)
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());
2485 public boolean equals(Object o
)
2487 synchronized (mutex
)
2493 public Object
get(Object key
)
2495 synchronized (mutex
)
2501 public int hashCode()
2503 synchronized (mutex
)
2505 return m
.hashCode();
2509 public boolean isEmpty()
2511 synchronized (mutex
)
2520 synchronized (mutex
)
2522 keys
= new SynchronizedSet(mutex
, m
.keySet());
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
)
2543 public Object
remove(Object o
)
2545 synchronized (mutex
)
2553 synchronized (mutex
)
2559 public String
toString()
2561 synchronized (mutex
)
2563 return m
.toString();
2567 public Collection
values()
2570 synchronized (mutex
)
2572 values
= new SynchronizedCollection(mutex
, m
.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>
2585 * Set s = Collections.synchronizedSet(new Set(...));
2589 * Iterator i = s.iterator();
2590 * while (i.hasNext())
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
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
2619 * Compatible with JDK 1.4.
2621 private static final long serialVersionUID
= 487447009682186044L;
2625 * @param s the set to wrap
2626 * @throws NullPointerException if s is null
2628 SynchronizedSet(Set s
)
2634 * Called only by trusted code to specify the mutex as well as the set.
2635 * @param sync the mutex
2638 SynchronizedSet(Object sync
, Set s
)
2643 public boolean equals(Object o
)
2645 synchronized (mutex
)
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>
2667 * SortedMap m = Collections.synchronizedSortedMap(new SortedMap(...));
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())
2677 * i = s2.iterator();
2678 * while (i.hasNext())
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
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
;
2718 * @param sm the map to wrap
2719 * @throws NullPointerException if sm is null
2721 SynchronizedSortedMap(SortedMap sm
)
2728 * Called only by trusted code to specify the mutex as well as the map.
2729 * @param sync the mutex
2732 SynchronizedSortedMap(Object sync
, SortedMap 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>
2794 * SortedSet s = Collections.synchronizedSortedSet(new SortedSet(...));
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())
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
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
;
2840 * @param ss the set to wrap
2841 * @throws NullPointerException if ss is null
2843 SynchronizedSortedSet(SortedSet ss
)
2850 * Called only by trusted code to specify the mutex as well as the set.
2851 * @param sync the mutex
2854 SynchronizedSortedSet(Object sync
, SortedSet ss
)
2860 public Comparator
comparator()
2862 synchronized (mutex
)
2864 return ss
.comparator();
2868 public Object
first()
2870 synchronized (mutex
)
2876 public SortedSet
headSet(Object toElement
)
2878 synchronized (mutex
)
2880 return new SynchronizedSortedSet(mutex
, ss
.headSet(toElement
));
2884 public Object
last()
2886 synchronized (mutex
)
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}.
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
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
2954 * Wrap a given collection.
2955 * @param c the collection to wrap
2956 * @throws NullPointerException if c is null
2958 UnmodifiableCollection(Collection c
)
2962 throw new NullPointerException();
2965 public boolean add(Object o
)
2967 throw new UnsupportedOperationException();
2970 public boolean addAll(Collection c
)
2972 throw new UnsupportedOperationException();
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()
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();
3020 public Object
[] 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
)
3058 public Object
next()
3063 public boolean 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}.
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
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
3102 * @author Eric Blake <ebb9@email.byu.edu>
3104 private static class UnmodifiableList
extends UnmodifiableCollection
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
3121 * Wrap a given list.
3122 * @param l the list to wrap
3123 * @throws NullPointerException if l is null
3125 UnmodifiableList(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
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
)
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
)
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}.
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
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;
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
;
3328 * @param m the map to wrap
3329 * @throws NullPointerException if m is null
3331 UnmodifiableMap(Map m
)
3335 throw new NullPointerException();
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());
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;
3376 * @param s the set to wrap
3378 UnmodifiableEntrySet(Set 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
)
3397 public Object
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
)
3428 public Object
get(Object 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()
3451 keys
= new UnmodifiableSet(m
.keySet());
3455 public void putAll(Map m
)
3457 throw new UnsupportedOperationException();
3460 public Object
remove(Object o
)
3462 throw new UnsupportedOperationException();
3470 public String
toString()
3472 return m
.toString();
3475 public Collection
values()
3478 values
= new UnmodifiableCollection(m
.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}.
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
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
3512 * Compatible with JDK 1.4.
3514 private static final long serialVersionUID
= -9215047833775013803L;
3518 * @param s the set to wrap
3519 * @throws NullPointerException if s is null
3521 UnmodifiableSet(Set s
)
3526 public boolean equals(Object 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}.
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
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
;
3579 * @param sm the map to wrap
3580 * @throws NullPointerException if sm is null
3582 UnmodifiableSortedMap(SortedMap 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}.
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
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
;
3661 * @param ss the set to wrap
3662 * @throws NullPointerException if ss is null
3664 UnmodifiableSortedSet(SortedSet ss
)
3670 public Comparator
comparator()
3672 return ss
.comparator();
3675 public Object
first()
3680 public SortedSet
headSet(Object toElement
)
3682 return new UnmodifiableSortedSet(ss
.headSet(toElement
));
3685 public Object
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