diff options
author | Tom Tromey <tromey@redhat.com> | 2005-07-16 01:27:14 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2005-07-16 01:27:14 +0000 |
commit | b0fa81eea9a270f23d6ad67ca7a6d25c18d20da1 (patch) | |
tree | 8762d1f992e2f725a6bde1ff966ed6f1e5f4f823 /libjava/java/util/Collections.java | |
parent | ea54b29342c8506acb4f858c68340c44b72e3532 (diff) | |
download | gcc-b0fa81eea9a270f23d6ad67ca7a6d25c18d20da1.zip gcc-b0fa81eea9a270f23d6ad67ca7a6d25c18d20da1.tar.gz gcc-b0fa81eea9a270f23d6ad67ca7a6d25c18d20da1.tar.bz2 |
Major merge with Classpath.
Removed many duplicate files.
* HACKING: Updated.x
* classpath: Imported new directory.
* standard.omit: New file.
* Makefile.in, aclocal.m4, configure: Rebuilt.
* sources.am: New file.
* configure.ac: Run Classpath configure script. Moved code around
to support. Disable xlib AWT peers (temporarily).
* Makefile.am (SUBDIRS): Added 'classpath'
(JAVAC): Removed.
(AM_CPPFLAGS): Added more -I options.
(BOOTCLASSPATH): Simplified.
Completely redid how sources are built.
Include sources.am.
* include/Makefile.am (tool_include__HEADERS): Removed jni.h.
* include/jni.h: Removed (in Classpath).
* scripts/classes.pl: Updated to look at built classes.
* scripts/makemake.tcl: New file.
* testsuite/libjava.jni/jni.exp (gcj_jni_compile_c_to_so): Added
-I options.
(gcj_jni_invocation_compile_c_to_binary): Likewise.
From-SVN: r102082
Diffstat (limited to 'libjava/java/util/Collections.java')
-rw-r--r-- | libjava/java/util/Collections.java | 5493 |
1 files changed, 0 insertions, 5493 deletions
diff --git a/libjava/java/util/Collections.java b/libjava/java/util/Collections.java deleted file mode 100644 index 64eb8da3..0000000 --- a/libjava/java/util/Collections.java +++ /dev/null @@ -1,5493 +0,0 @@ -/* Collections.java -- Utility class with methods to operate on collections - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005 - Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.io.Serializable; - -/** - * Utility class consisting of static methods that operate on, or return - * Collections. Contains methods to sort, search, reverse, fill and shuffle - * Collections, methods to facilitate interoperability with legacy APIs that - * are unaware of collections, a method to return a list which consists of - * multiple copies of one element, and methods which "wrap" collections to give - * them extra properties, such as thread-safety and unmodifiability. - * <p> - * - * All methods which take a collection throw a {@link NullPointerException} if - * that collection is null. Algorithms which can change a collection may, but - * are not required, to throw the {@link UnsupportedOperationException} that - * the underlying collection would throw during an attempt at modification. - * For example, - * <code>Collections.singleton("").addAll(Collections.EMPTY_SET)</code> - * does not throw a exception, even though addAll is an unsupported operation - * on a singleton; the reason for this is that addAll did not attempt to - * modify the set. - * - * @author Original author unknown - * @author Eric Blake (ebb9@email.byu.edu) - * @see Collection - * @see Set - * @see List - * @see Map - * @see Arrays - * @since 1.2 - * @status updated to 1.4 - */ -public class Collections -{ - /** - * Constant used to decide cutoff for when a non-RandomAccess list should - * be treated as sequential-access. Basically, quadratic behavior is - * acceptable for small lists when the overhead is so small in the first - * place. I arbitrarily set it to 16, so it may need some tuning. - */ - private static final int LARGE_LIST_SIZE = 16; - - /** - * Determines if a list should be treated as a sequential-access one. - * Rather than the old method of JDK 1.3 of assuming only instanceof - * AbstractSequentialList should be sequential, this uses the new method - * of JDK 1.4 of assuming anything that does NOT implement RandomAccess - * and exceeds a large (unspecified) size should be sequential. - * - * @param l the list to check - * @return <code>true</code> if it should be treated as sequential-access - */ - private static boolean isSequential(List l) - { - return ! (l instanceof RandomAccess) && l.size() > LARGE_LIST_SIZE; - } - - /** - * This class is non-instantiable. - */ - private Collections() - { - } - - /** - * An immutable, serializable, empty Set. - * @see Serializable - */ - public static final Set EMPTY_SET = new EmptySet(); - - /** - * The implementation of {@link #EMPTY_SET}. This class name is required - * for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class EmptySet extends AbstractSet - implements Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 1582296315990362920L; - - /** - * A private constructor adds overhead. - */ - EmptySet() - { - } - - /** - * The size: always 0! - * @return 0. - */ - public int size() - { - return 0; - } - - /** - * Returns an iterator that does not iterate. - * @return A non-iterating iterator. - */ - // This is really cheating! I think it's perfectly valid, though. - public Iterator iterator() - { - return EMPTY_LIST.iterator(); - } - - // The remaining methods are optional, but provide a performance - // advantage by not allocating unnecessary iterators in AbstractSet. - /** - * The empty set never contains anything. - * @param o The object to search for. - * @return <code>false</code>. - */ - public boolean contains(Object o) - { - return false; - } - - /** - * This is true only if the given collection is also empty. - * @param c The collection of objects which are to be compared - * against the members of this set. - * @return <code>true</code> if c is empty. - */ - public boolean containsAll(Collection c) - { - return c.isEmpty(); - } - - /** - * Equal only if the other set is empty. - * @param o The object to compare with this set. - * @return <code>true</code> if o is an empty instance of <code>Set</code>. - */ - public boolean equals(Object o) - { - return o instanceof Set && ((Set) o).isEmpty(); - } - - /** - * The hashcode is always 0. - * @return 0. - */ - public int hashCode() - { - return 0; - } - - /** - * Always succeeds with a <code>false</code> result. - * @param o The object to remove. - * @return <code>false</code>. - */ - public boolean remove(Object o) - { - return false; - } - - /** - * Always succeeds with a <code>false</code> result. - * @param c The collection of objects which should - * all be removed from this set. - * @return <code>false</code>. - */ - public boolean removeAll(Collection c) - { - return false; - } - - /** - * Always succeeds with a <code>false</code> result. - * @param c The collection of objects which should - * all be retained within this set. - * @return <code>false</code>. - */ - public boolean retainAll(Collection c) - { - return false; - } - - /** - * The array is always empty. - * @return A new array with a size of 0. - */ - public Object[] toArray() - { - return new Object[0]; - } - - /** - * We don't even need to use reflection! - * @param a An existing array, which can be empty. - * @return The original array with any existing - * initial element set to null. - */ - public Object[] toArray(Object[] a) - { - if (a.length > 0) - a[0] = null; - return a; - } - - /** - * The string never changes. - * - * @return the string "[]". - */ - public String toString() - { - return "[]"; - } - } // class EmptySet - - /** - * An immutable, serializable, empty List, which implements RandomAccess. - * @see Serializable - * @see RandomAccess - */ - public static final List EMPTY_LIST = new EmptyList(); - - /** - * The implementation of {@link #EMPTY_LIST}. This class name is required - * for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class EmptyList extends AbstractList - implements Serializable, RandomAccess - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 8842843931221139166L; - - /** - * A private constructor adds overhead. - */ - EmptyList() - { - } - - /** - * The size is always 0. - * @return 0. - */ - public int size() - { - return 0; - } - - /** - * No matter the index, it is out of bounds. This - * method never returns, throwing an exception instead. - * - * @param index The index of the element to retrieve. - * @return the object at the specified index. - * @throws IndexOutofBoundsException as any given index - * is outside the bounds of an empty array. - */ - public Object get(int index) - { - throw new IndexOutOfBoundsException(); - } - - // The remaining methods are optional, but provide a performance - // advantage by not allocating unnecessary iterators in AbstractList. - /** - * Never contains anything. - * @param o The object to search for. - * @return <code>false</code>. - */ - public boolean contains(Object o) - { - return false; - } - - /** - * This is true only if the given collection is also empty. - * @param c The collection of objects, which should be compared - * against the members of this list. - * @return <code>true</code> if c is also empty. - */ - public boolean containsAll(Collection c) - { - return c.isEmpty(); - } - - /** - * Equal only if the other list is empty. - * @param o The object to compare against this list. - * @return <code>true</code> if o is also an empty instance of - * <code>List</code>. - */ - public boolean equals(Object o) - { - return o instanceof List && ((List) o).isEmpty(); - } - - /** - * The hashcode is always 1. - * @return 1. - */ - public int hashCode() - { - return 1; - } - - /** - * Returns -1. - * @param o The object to search for. - * @return -1. - */ - public int indexOf(Object o) - { - return -1; - } - - /** - * Returns -1. - * @param o The object to search for. - * @return -1. - */ - public int lastIndexOf(Object o) - { - return -1; - } - - /** - * Always succeeds with <code>false</code> result. - * @param o The object to remove. - * @return -1. - */ - public boolean remove(Object o) - { - return false; - } - - /** - * Always succeeds with <code>false</code> result. - * @param c The collection of objects which should - * all be removed from this list. - * @return <code>false</code>. - */ - public boolean removeAll(Collection c) - { - return false; - } - - /** - * Always succeeds with <code>false</code> result. - * @param c The collection of objects which should - * all be retained within this list. - * @return <code>false</code>. - */ - public boolean retainAll(Collection c) - { - return false; - } - - /** - * The array is always empty. - * @return A new array with a size of 0. - */ - public Object[] toArray() - { - return new Object[0]; - } - - /** - * We don't even need to use reflection! - * @param a An existing array, which can be empty. - * @return The original array with any existing - * initial element set to null. - */ - public Object[] toArray(Object[] a) - { - if (a.length > 0) - a[0] = null; - return a; - } - - /** - * The string never changes. - * - * @return the string "[]". - */ - public String toString() - { - return "[]"; - } - } // class EmptyList - - /** - * An immutable, serializable, empty Map. - * @see Serializable - */ - public static final Map EMPTY_MAP = new EmptyMap(); - - /** - * The implementation of {@link #EMPTY_MAP}. This class name is required - * for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class EmptyMap extends AbstractMap - implements Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 6428348081105594320L; - - /** - * A private constructor adds overhead. - */ - EmptyMap() - { - } - - /** - * There are no entries. - * @return The empty set. - */ - public Set entrySet() - { - return EMPTY_SET; - } - - // The remaining methods are optional, but provide a performance - // advantage by not allocating unnecessary iterators in AbstractMap. - /** - * No entries! - * @param key The key to search for. - * @return <code>false</code>. - */ - public boolean containsKey(Object key) - { - return false; - } - - /** - * No entries! - * @param value The value to search for. - * @return <code>false</code>. - */ - public boolean containsValue(Object value) - { - return false; - } - - /** - * Equal to all empty maps. - * @param o The object o to compare against this map. - * @return <code>true</code> if o is also an empty instance of - * <code>Map</code>. - */ - public boolean equals(Object o) - { - return o instanceof Map && ((Map) o).isEmpty(); - } - - /** - * No mappings, so this returns null. - * @param o The key of the object to retrieve. - * @return null. - */ - public Object get(Object o) - { - return null; - } - - /** - * The hashcode is always 0. - * @return 0. - */ - public int hashCode() - { - return 0; - } - - /** - * No entries. - * @return The empty set. - */ - public Set keySet() - { - return EMPTY_SET; - } - - /** - * Remove always succeeds, with null result. - * @param o The key of the mapping to remove. - * @return null, as there is never a mapping for o. - */ - public Object remove(Object o) - { - return null; - } - - /** - * Size is always 0. - * @return 0. - */ - public int size() - { - return 0; - } - - /** - * No entries. Technically, EMPTY_SET, while more specific than a general - * Collection, will work. Besides, that's what the JDK uses! - * @return The empty set. - */ - public Collection values() - { - return EMPTY_SET; - } - - /** - * The string never changes. - * - * @return the string "[]". - */ - public String toString() - { - return "[]"; - } - } // class EmptyMap - - - /** - * Compare two objects with or without a Comparator. If c is null, uses the - * natural ordering. Slightly slower than doing it inline if the JVM isn't - * clever, but worth it for removing a duplicate of the search code. - * Note: This code is also used in Arrays (for sort as well as search). - */ - static final int compare(Object o1, Object o2, Comparator c) - { - return c == null ? ((Comparable) o1).compareTo(o2) : c.compare(o1, o2); - } - - /** - * Perform a binary search of a List for a key, using the natural ordering of - * the elements. The list must be sorted (as by the sort() method) - if it is - * not, the behavior of this method is undefined, and may be an infinite - * loop. Further, the key must be comparable with every item in the list. If - * the list contains the key more than once, any one of them may be found. - * <p> - * - * This algorithm behaves in log(n) time for {@link RandomAccess} lists, - * and uses a linear search with O(n) link traversals and log(n) comparisons - * with {@link AbstractSequentialList} lists. Note: although the - * specification allows for an infinite loop if the list is unsorted, it will - * not happen in this (Classpath) implementation. - * - * @param l the list to search (must be sorted) - * @param key the value to search for - * @return the index at which the key was found, or -n-1 if it was not - * found, where n is the index of the first value higher than key or - * a.length if there is no such value - * @throws ClassCastException if key could not be compared with one of the - * elements of l - * @throws NullPointerException if a null element has compareTo called - * @see #sort(List) - */ - public static int binarySearch(List l, Object key) - { - return binarySearch(l, key, null); - } - - /** - * Perform a binary search of a List for a key, using a supplied Comparator. - * The list must be sorted (as by the sort() method with the same Comparator) - * - if it is not, the behavior of this method is undefined, and may be an - * infinite loop. Further, the key must be comparable with every item in the - * list. If the list contains the key more than once, any one of them may be - * found. If the comparator is null, the elements' natural ordering is used. - * <p> - * - * This algorithm behaves in log(n) time for {@link RandomAccess} lists, - * and uses a linear search with O(n) link traversals and log(n) comparisons - * with {@link AbstractSequentialList} lists. Note: although the - * specification allows for an infinite loop if the list is unsorted, it will - * not happen in this (Classpath) implementation. - * - * @param l the list to search (must be sorted) - * @param key the value to search for - * @param c the comparator by which the list is sorted - * @return the index at which the key was found, or -n-1 if it was not - * found, where n is the index of the first value higher than key or - * a.length if there is no such value - * @throws ClassCastException if key could not be compared with one of the - * elements of l - * @throws NullPointerException if a null element is compared with natural - * ordering (only possible when c is null) - * @see #sort(List, Comparator) - */ - public static int binarySearch(List l, Object key, Comparator c) - { - int pos = 0; - int low = 0; - int hi = l.size() - 1; - - // We use a linear search with log(n) comparisons using an iterator - // if the list is sequential-access. - if (isSequential(l)) - { - ListIterator itr = l.listIterator(); - int i = 0; - Object o = itr.next(); // Assumes list is not empty (see isSequential) - boolean forward = true; - while (low <= hi) - { - pos = (low + hi) >> 1; - if (i < pos) - { - if (!forward) - itr.next(); // Changing direction first. - for ( ; i != pos; i++, o = itr.next()); - forward = true; - } - else - { - if (forward) - itr.previous(); // Changing direction first. - for ( ; i != pos; i--, o = itr.previous()); - forward = false; - } - final int d = compare(key, o, c); - if (d == 0) - return pos; - else if (d < 0) - hi = pos - 1; - else - // This gets the insertion point right on the last loop - low = ++pos; - } - } - else - { - while (low <= hi) - { - pos = (low + hi) >> 1; - final int d = compare(key, l.get(pos), c); - if (d == 0) - return pos; - else if (d < 0) - hi = pos - 1; - else - // This gets the insertion point right on the last loop - low = ++pos; - } - } - - // If we failed to find it, we do the same whichever search we did. - return -pos - 1; - } - - /** - * Copy one list to another. If the destination list is longer than the - * source list, the remaining elements are unaffected. This method runs in - * linear time. - * - * @param dest the destination list - * @param source the source list - * @throws IndexOutOfBoundsException if the destination list is shorter - * than the source list (the destination will be unmodified) - * @throws UnsupportedOperationException if dest.listIterator() does not - * support the set operation - */ - public static void copy(List dest, List source) - { - int pos = source.size(); - if (dest.size() < pos) - throw new IndexOutOfBoundsException("Source does not fit in dest"); - - Iterator i1 = source.iterator(); - ListIterator i2 = dest.listIterator(); - - while (--pos >= 0) - { - i2.next(); - i2.set(i1.next()); - } - } - - /** - * Returns an Enumeration over a collection. This allows interoperability - * with legacy APIs that require an Enumeration as input. - * - * @param c the Collection to iterate over - * @return an Enumeration backed by an Iterator over c - */ - public static Enumeration enumeration(Collection c) - { - final Iterator i = c.iterator(); - return new Enumeration() - { - /** - * Returns <code>true</code> if there are more elements to - * be enumerated. - * - * @return The result of <code>hasNext()</code> - * called on the underlying iterator. - */ - public final boolean hasMoreElements() - { - return i.hasNext(); - } - - /** - * Returns the next element to be enumerated. - * - * @return The result of <code>next()</code> - * called on the underlying iterator. - */ - public final Object nextElement() - { - return i.next(); - } - }; - } - - /** - * Replace every element of a list with a given value. This method runs in - * linear time. - * - * @param l the list to fill. - * @param val the object to vill the list with. - * @throws UnsupportedOperationException if l.listIterator() does not - * support the set operation. - */ - public static void fill(List l, Object val) - { - ListIterator itr = l.listIterator(); - for (int i = l.size() - 1; i >= 0; --i) - { - itr.next(); - itr.set(val); - } - } - - /** - * Returns the starting index where the specified sublist first occurs - * in a larger list, or -1 if there is no matching position. If - * <code>target.size() > source.size()</code>, this returns -1, - * otherwise this implementation uses brute force, checking for - * <code>source.sublist(i, i + target.size()).equals(target)</code> - * for all possible i. - * - * @param source the list to search - * @param target the sublist to search for - * @return the index where found, or -1 - * @since 1.4 - */ - public static int indexOfSubList(List source, List target) - { - int ssize = source.size(); - for (int i = 0, j = target.size(); j <= ssize; i++, j++) - if (source.subList(i, j).equals(target)) - return i; - return -1; - } - - /** - * Returns the starting index where the specified sublist last occurs - * in a larger list, or -1 if there is no matching position. If - * <code>target.size() > source.size()</code>, this returns -1, - * otherwise this implementation uses brute force, checking for - * <code>source.sublist(i, i + target.size()).equals(target)</code> - * for all possible i. - * - * @param source the list to search - * @param target the sublist to search for - * @return the index where found, or -1 - * @since 1.4 - */ - public static int lastIndexOfSubList(List source, List target) - { - int ssize = source.size(); - for (int i = ssize - target.size(), j = ssize; i >= 0; i--, j--) - if (source.subList(i, j).equals(target)) - return i; - return -1; - } - - /** - * Returns an ArrayList holding the elements visited by a given - * Enumeration. This method exists for interoperability between legacy - * APIs and the new Collection API. - * - * @param e the enumeration to put in a list - * @return a list containing the enumeration elements - * @see ArrayList - * @since 1.4 - */ - public static ArrayList list(Enumeration e) - { - ArrayList l = new ArrayList(); - while (e.hasMoreElements()) - l.add(e.nextElement()); - return l; - } - - /** - * Find the maximum element in a Collection, according to the natural - * ordering of the elements. This implementation iterates over the - * Collection, so it works in linear time. - * - * @param c the Collection to find the maximum element of - * @return the maximum element of c - * @exception NoSuchElementException if c is empty - * @exception ClassCastException if elements in c are not mutually comparable - * @exception NullPointerException if null.compareTo is called - */ - public static Object max(Collection c) - { - return max(c, null); - } - - /** - * Find the maximum element in a Collection, according to a specified - * Comparator. This implementation iterates over the Collection, so it - * works in linear time. - * - * @param c the Collection to find the maximum element of - * @param order the Comparator to order the elements by, or null for natural - * ordering - * @return the maximum element of c - * @throws NoSuchElementException if c is empty - * @throws ClassCastException if elements in c are not mutually comparable - * @throws NullPointerException if null is compared by natural ordering - * (only possible when order is null) - */ - public static Object max(Collection c, Comparator order) - { - Iterator itr = c.iterator(); - Object max = itr.next(); // throws NoSuchElementException - int csize = c.size(); - for (int i = 1; i < csize; i++) - { - Object o = itr.next(); - if (compare(max, o, order) < 0) - max = o; - } - return max; - } - - /** - * Find the minimum element in a Collection, according to the natural - * ordering of the elements. This implementation iterates over the - * Collection, so it works in linear time. - * - * @param c the Collection to find the minimum element of - * @return the minimum element of c - * @throws NoSuchElementException if c is empty - * @throws ClassCastException if elements in c are not mutually comparable - * @throws NullPointerException if null.compareTo is called - */ - public static Object min(Collection c) - { - return min(c, null); - } - - /** - * Find the minimum element in a Collection, according to a specified - * Comparator. This implementation iterates over the Collection, so it - * works in linear time. - * - * @param c the Collection to find the minimum element of - * @param order the Comparator to order the elements by, or null for natural - * ordering - * @return the minimum element of c - * @throws NoSuchElementException if c is empty - * @throws ClassCastException if elements in c are not mutually comparable - * @throws NullPointerException if null is compared by natural ordering - * (only possible when order is null) - */ - public static Object min(Collection c, Comparator order) - { - Iterator itr = c.iterator(); - Object min = itr.next(); // throws NoSuchElementExcception - int csize = c.size(); - for (int i = 1; i < csize; i++) - { - Object o = itr.next(); - if (compare(min, o, order) > 0) - min = o; - } - return min; - } - - /** - * Creates an immutable list consisting of the same object repeated n times. - * The returned object is tiny, consisting of only a single reference to the - * object and a count of the number of elements. It is Serializable, and - * implements RandomAccess. You can use it in tandem with List.addAll for - * fast list construction. - * - * @param n the number of times to repeat the object - * @param o the object to repeat - * @return a List consisting of n copies of o - * @throws IllegalArgumentException if n < 0 - * @see List#addAll(Collection) - * @see Serializable - * @see RandomAccess - */ - public static List nCopies(final int n, final Object o) - { - return new CopiesList(n, o); - } - - /** - * The implementation of {@link #nCopies(int, Object)}. This class name - * is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class CopiesList extends AbstractList - implements Serializable, RandomAccess - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 2739099268398711800L; - - /** - * The count of elements in this list. - * @serial the list size - */ - private final int n; - - /** - * The repeated list element. - * @serial the list contents - */ - private final Object element; - - /** - * Constructs the list. - * - * @param n the count - * @param o the object - * @throws IllegalArgumentException if n < 0 - */ - CopiesList(int n, Object o) - { - if (n < 0) - throw new IllegalArgumentException(); - this.n = n; - element = o; - } - - /** - * The size is fixed. - * @return The size of the list. - */ - public int size() - { - return n; - } - - /** - * The same element is returned. - * @param index The index of the element to be returned (irrelevant - * as the list contains only copies of <code>element</code>). - * @return The element used by this list. - */ - public Object get(int index) - { - if (index < 0 || index >= n) - throw new IndexOutOfBoundsException(); - return element; - } - - // The remaining methods are optional, but provide a performance - // advantage by not allocating unnecessary iterators in AbstractList. - /** - * This list only contains one element. - * @param o The object to search for. - * @return <code>true</code> if o is the element used by this list. - */ - public boolean contains(Object o) - { - return n > 0 && equals(o, element); - } - - /** - * The index is either 0 or -1. - * @param o The object to find the index of. - * @return 0 if <code>o == element</code>, -1 if not. - */ - public int indexOf(Object o) - { - return (n > 0 && equals(o, element)) ? 0 : -1; - } - - /** - * The index is either n-1 or -1. - * @param o The object to find the last index of. - * @return The last index in the list if <code>o == element</code>, - * -1 if not. - */ - public int lastIndexOf(Object o) - { - return equals(o, element) ? n - 1 : -1; - } - - /** - * A subList is just another CopiesList. - * @param from The starting bound of the sublist. - * @param to The ending bound of the sublist. - * @return A list of copies containing <code>from - to</code> - * elements, all of which are equal to the element - * used by this list. - */ - public List subList(int from, int to) - { - if (from < 0 || to > n) - throw new IndexOutOfBoundsException(); - return new CopiesList(to - from, element); - } - - /** - * The array is easy. - * @return An array of size n filled with copies of - * the element used by this list. - */ - public Object[] toArray() - { - Object[] a = new Object[n]; - Arrays.fill(a, element); - return a; - } - - /** - * The string is easy to generate. - * @return A string representation of the list. - */ - public String toString() - { - StringBuffer r = new StringBuffer("{"); - for (int i = n - 1; --i > 0; ) - r.append(element).append(", "); - r.append(element).append("}"); - return r.toString(); - } - } // class CopiesList - - /** - * Replace all instances of one object with another in the specified list. - * The list does not change size. An element e is replaced if - * <code>oldval == null ? e == null : oldval.equals(e)</code>. - * - * @param list the list to iterate over - * @param oldval the element to replace - * @param newval the new value for the element - * @return <code>true</code> if a replacement occurred. - * @throws UnsupportedOperationException if the list iterator does not allow - * for the set operation - * @throws ClassCastException if newval is of a type which cannot be added - * to the list - * @throws IllegalArgumentException if some other aspect of newval stops - * it being added to the list - * @since 1.4 - */ - public static boolean replaceAll(List list, Object oldval, Object newval) - { - ListIterator itr = list.listIterator(); - boolean replace_occured = false; - for (int i = list.size(); --i >= 0; ) - if (AbstractCollection.equals(oldval, itr.next())) - { - itr.set(newval); - replace_occured = true; - } - return replace_occured; - } - - /** - * Reverse a given list. This method works in linear time. - * - * @param l the list to reverse - * @throws UnsupportedOperationException if l.listIterator() does not - * support the set operation - */ - public static void reverse(List l) - { - ListIterator i1 = l.listIterator(); - int pos1 = 1; - int pos2 = l.size(); - ListIterator i2 = l.listIterator(pos2); - while (pos1 < pos2) - { - Object o = i1.next(); - i1.set(i2.previous()); - i2.set(o); - ++pos1; - --pos2; - } - } - - /** - * Get a comparator that implements the reverse of natural ordering. In - * other words, this sorts Comparable objects opposite of how their - * compareTo method would sort. This makes it easy to sort into reverse - * order, by simply passing Collections.reverseOrder() to the sort method. - * The return value of this method is Serializable. - * - * @return a comparator that imposes reverse natural ordering - * @see Comparable - * @see Serializable - */ - public static Comparator reverseOrder() - { - return rcInstance; - } - - /** - * The object for {@link #reverseOrder()}. - */ - private static final ReverseComparator rcInstance = new ReverseComparator(); - - /** - * The implementation of {@link #reverseOrder()}. This class name - * is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class ReverseComparator - implements Comparator, Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 7207038068494060240L; - - /** - * A private constructor adds overhead. - */ - ReverseComparator() - { - } - - /** - * Compare two objects in reverse natural order. - * - * @param a the first object - * @param b the second object - * @return <, ==, or > 0 according to b.compareTo(a) - */ - public int compare(Object a, Object b) - { - return ((Comparable) b).compareTo(a); - } - } - - /** - * Rotate the elements in a list by a specified distance. After calling this - * method, the element now at index <code>i</code> was formerly at index - * <code>(i - distance) mod list.size()</code>. The list size is unchanged. - * <p> - * - * For example, suppose a list contains <code>[t, a, n, k, s]</code>. After - * either <code>Collections.rotate(l, 4)</code> or - * <code>Collections.rotate(l, -1)</code>, the new contents are - * <code>[s, t, a, n, k]</code>. This can be applied to sublists to rotate - * just a portion of the list. For example, to move element <code>a</code> - * forward two positions in the original example, use - * <code>Collections.rotate(l.subList(1, 3+1), -1)</code>, which will - * result in <code>[t, n, k, a, s]</code>. - * <p> - * - * If the list is small or implements {@link RandomAccess}, the - * implementation exchanges the first element to its destination, then the - * displaced element, and so on until a circuit has been completed. The - * process is repeated if needed on the second element, and so forth, until - * all elements have been swapped. For large non-random lists, the - * implementation breaks the list into two sublists at index - * <code>-distance mod size</code>, calls {@link #reverse(List)} on the - * pieces, then reverses the overall list. - * - * @param list the list to rotate - * @param distance the distance to rotate by; unrestricted in value - * @throws UnsupportedOperationException if the list does not support set - * @since 1.4 - */ - public static void rotate(List list, int distance) - { - int size = list.size(); - if (size == 0) - return; - distance %= size; - if (distance == 0) - return; - if (distance < 0) - distance += size; - - if (isSequential(list)) - { - reverse(list); - reverse(list.subList(0, distance)); - reverse(list.subList(distance, size)); - } - else - { - // Determine the least common multiple of distance and size, as there - // are (distance / LCM) loops to cycle through. - int a = size; - int lcm = distance; - int b = a % lcm; - while (b != 0) - { - a = lcm; - lcm = b; - b = a % lcm; - } - - // Now, make the swaps. We must take the remainder every time through - // the inner loop so that we don't overflow i to negative values. - while (--lcm >= 0) - { - Object o = list.get(lcm); - for (int i = lcm + distance; i != lcm; i = (i + distance) % size) - o = list.set(i, o); - list.set(lcm, o); - } - } - } - - /** - * Shuffle a list according to a default source of randomness. The algorithm - * used iterates backwards over the list, swapping each element with an - * element randomly selected from the elements in positions less than or - * equal to it (using r.nextInt(int)). - * <p> - * - * This algorithm would result in a perfectly fair shuffle (that is, each - * element would have an equal chance of ending up in any position) if r were - * a perfect source of randomness. In practice the results are merely very - * close to perfect. - * <p> - * - * This method operates in linear time. To do this on large lists which do - * not implement {@link RandomAccess}, a temporary array is used to acheive - * this speed, since it would be quadratic access otherwise. - * - * @param l the list to shuffle - * @throws UnsupportedOperationException if l.listIterator() does not - * support the set operation - */ - public static void shuffle(List l) - { - if (defaultRandom == null) - { - synchronized (Collections.class) - { - if (defaultRandom == null) - defaultRandom = new Random(); - } - } - shuffle(l, defaultRandom); - } - - /** - * Cache a single Random object for use by shuffle(List). This improves - * performance as well as ensuring that sequential calls to shuffle() will - * not result in the same shuffle order occurring: the resolution of - * System.currentTimeMillis() is not sufficient to guarantee a unique seed. - */ - private static Random defaultRandom = null; - - /** - * Shuffle a list according to a given source of randomness. The algorithm - * used iterates backwards over the list, swapping each element with an - * element randomly selected from the elements in positions less than or - * equal to it (using r.nextInt(int)). - * <p> - * - * This algorithm would result in a perfectly fair shuffle (that is, each - * element would have an equal chance of ending up in any position) if r were - * a perfect source of randomness. In practise (eg if r = new Random()) the - * results are merely very close to perfect. - * <p> - * - * This method operates in linear time. To do this on large lists which do - * not implement {@link RandomAccess}, a temporary array is used to acheive - * this speed, since it would be quadratic access otherwise. - * - * @param l the list to shuffle - * @param r the source of randomness to use for the shuffle - * @throws UnsupportedOperationException if l.listIterator() does not - * support the set operation - */ - public static void shuffle(List l, Random r) - { - int lsize = l.size(); - ListIterator i = l.listIterator(lsize); - boolean sequential = isSequential(l); - Object[] a = null; // stores a copy of the list for the sequential case - - if (sequential) - a = l.toArray(); - - for (int pos = lsize - 1; pos > 0; --pos) - { - // Obtain a random position to swap with. pos + 1 is used so that the - // range of the random number includes the current position. - int swap = r.nextInt(pos + 1); - - // Swap the desired element. - Object o; - if (sequential) - { - o = a[swap]; - a[swap] = i.previous(); - } - else - o = l.set(swap, i.previous()); - - i.set(o); - } - } - - - /** - * Obtain an immutable Set consisting of a single element. The return value - * of this method is Serializable. - * - * @param o the single element - * @return an immutable Set containing only o - * @see Serializable - */ - public static Set singleton(Object o) - { - return new SingletonSet(o); - } - - /** - * The implementation of {@link #singleton(Object)}. This class name - * is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class SingletonSet extends AbstractSet - implements Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 3193687207550431679L; - - - /** - * The single element; package visible for use in nested class. - * @serial the singleton - */ - final Object element; - - /** - * Construct a singleton. - * @param o the element - */ - SingletonSet(Object o) - { - element = o; - } - - /** - * The size: always 1! - * @return 1. - */ - public int size() - { - return 1; - } - - /** - * Returns an iterator over the lone element. - */ - public Iterator iterator() - { - return new Iterator() - { - /** - * Flag to indicate whether or not the element has - * been retrieved. - */ - private boolean hasNext = true; - - /** - * Returns <code>true</code> if elements still remain to be - * iterated through. - * - * @return <code>true</code> if the element has not yet been returned. - */ - public boolean hasNext() - { - return hasNext; - } - - /** - * Returns the element. - * - * @return The element used by this singleton. - * @throws NoSuchElementException if the object - * has already been retrieved. - */ - public Object next() - { - if (hasNext) - { - hasNext = false; - return element; - } - else - throw new NoSuchElementException(); - } - - /** - * Removes the element from the singleton. - * As this set is immutable, this will always - * throw an exception. - * - * @throws UnsupportedOperationException as the - * singleton set doesn't support - * <code>remove()</code>. - */ - public void remove() - { - throw new UnsupportedOperationException(); - } - }; - } - - // The remaining methods are optional, but provide a performance - // advantage by not allocating unnecessary iterators in AbstractSet. - /** - * The set only contains one element. - * - * @param o The object to search for. - * @return <code>true</code> if o == the element of the singleton. - */ - public boolean contains(Object o) - { - return equals(o, element); - } - - /** - * This is true if the other collection only contains the element. - * - * @param c A collection to compare against this singleton. - * @return <code>true</code> if c only contains either no elements or - * elements equal to the element in this singleton. - */ - public boolean containsAll(Collection c) - { - Iterator i = c.iterator(); - int pos = c.size(); - while (--pos >= 0) - if (! equals(i.next(), element)) - return false; - return true; - } - - /** - * The hash is just that of the element. - * - * @return The hashcode of the element. - */ - public int hashCode() - { - return hashCode(element); - } - - /** - * Returning an array is simple. - * - * @return An array containing the element. - */ - public Object[] toArray() - { - return new Object[] {element}; - } - - /** - * Obvious string. - * - * @return The string surrounded by enclosing - * square brackets. - */ - public String toString() - { - return "[" + element + "]"; - } - } // class SingletonSet - - /** - * Obtain an immutable List consisting of a single element. The return value - * of this method is Serializable, and implements RandomAccess. - * - * @param o the single element - * @return an immutable List containing only o - * @see Serializable - * @see RandomAccess - * @since 1.3 - */ - public static List singletonList(Object o) - { - return new SingletonList(o); - } - - /** - * The implementation of {@link #singletonList(Object)}. This class name - * is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class SingletonList extends AbstractList - implements Serializable, RandomAccess - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 3093736618740652951L; - - /** - * The single element. - * @serial the singleton - */ - private final Object element; - - /** - * Construct a singleton. - * @param o the element - */ - SingletonList(Object o) - { - element = o; - } - - /** - * The size: always 1! - * @return 1. - */ - public int size() - { - return 1; - } - - /** - * Only index 0 is valid. - * @param index The index of the element - * to retrieve. - * @return The singleton's element if the - * index is 0. - * @throws IndexOutOfBoundsException if - * index is not 0. - */ - public Object get(int index) - { - if (index == 0) - return element; - throw new IndexOutOfBoundsException(); - } - - // The remaining methods are optional, but provide a performance - // advantage by not allocating unnecessary iterators in AbstractList. - /** - * The set only contains one element. - * - * @param o The object to search for. - * @return <code>true</code> if o == the singleton element. - */ - public boolean contains(Object o) - { - return equals(o, element); - } - - /** - * This is true if the other collection only contains the element. - * - * @param c A collection to compare against this singleton. - * @return <code>true</code> if c only contains either no elements or - * elements equal to the element in this singleton. - */ - public boolean containsAll(Collection c) - { - Iterator i = c.iterator(); - int pos = c.size(); - while (--pos >= 0) - if (! equals(i.next(), element)) - return false; - return true; - } - - /** - * Speed up the hashcode computation. - * - * @return The hashcode of the list, based - * on the hashcode of the singleton element. - */ - public int hashCode() - { - return 31 + hashCode(element); - } - - /** - * Either the list has it or not. - * - * @param o The object to find the first index of. - * @return 0 if o is the singleton element, -1 if not. - */ - public int indexOf(Object o) - { - return equals(o, element) ? 0 : -1; - } - - /** - * Either the list has it or not. - * - * @param o The object to find the last index of. - * @return 0 if o is the singleton element, -1 if not. - */ - public int lastIndexOf(Object o) - { - return equals(o, element) ? 0 : -1; - } - - /** - * Sublists are limited in scope. - * - * @param from The starting bound for the sublist. - * @param to The ending bound for the sublist. - * @return Either an empty list if both bounds are - * 0 or 1, or this list if the bounds are 0 and 1. - * @throws IllegalArgumentException if <code>from > to</code> - * @throws IndexOutOfBoundsException if either bound is greater - * than 1. - */ - public List subList(int from, int to) - { - if (from == to && (to == 0 || to == 1)) - return EMPTY_LIST; - if (from == 0 && to == 1) - return this; - if (from > to) - throw new IllegalArgumentException(); - throw new IndexOutOfBoundsException(); - } - - /** - * Returning an array is simple. - * - * @return An array containing the element. - */ - public Object[] toArray() - { - return new Object[] {element}; - } - - /** - * Obvious string. - * - * @return The string surrounded by enclosing - * square brackets. - */ - public String toString() - { - return "[" + element + "]"; - } - } // class SingletonList - - /** - * Obtain an immutable Map consisting of a single key-value pair. - * The return value of this method is Serializable. - * - * @param key the single key - * @param value the single value - * @return an immutable Map containing only the single key-value pair - * @see Serializable - * @since 1.3 - */ - public static Map singletonMap(Object key, Object value) - { - return new SingletonMap(key, value); - } - - /** - * The implementation of {@link #singletonMap(Object)}. This class name - * is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class SingletonMap extends AbstractMap - implements Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -6979724477215052911L; - - /** - * The single key. - * @serial the singleton key - */ - private final Object k; - - /** - * The corresponding value. - * @serial the singleton value - */ - private final Object v; - - /** - * Cache the entry set. - */ - private transient Set entries; - - /** - * Construct a singleton. - * @param key the key - * @param value the value - */ - SingletonMap(Object key, Object value) - { - k = key; - v = value; - } - - /** - * There is a single immutable entry. - * - * @return A singleton containing the map entry. - */ - public Set entrySet() - { - if (entries == null) - entries = singleton(new AbstractMap.BasicMapEntry(k, v) - { - /** - * Sets the value of the map entry to the supplied value. - * An exception is always thrown, as the map is immutable. - * - * @param o The new value. - * @return The old value. - * @throws UnsupportedOperationException as setting the value - * is not supported. - */ - public Object setValue(Object o) - { - throw new UnsupportedOperationException(); - } - }); - return entries; - } - - // The remaining methods are optional, but provide a performance - // advantage by not allocating unnecessary iterators in AbstractMap. - /** - * Single entry. - * - * @param key The key to look for. - * @return <code>true</code> if the key is the same as the one used by - * this map. - */ - public boolean containsKey(Object key) - { - return equals(key, k); - } - - /** - * Single entry. - * - * @param value The value to look for. - * @return <code>true</code> if the value is the same as the one used by - * this map. - */ - public boolean containsValue(Object value) - { - return equals(value, v); - } - - /** - * Single entry. - * - * @param key The key of the value to be retrieved. - * @return The singleton value if the key is the same as the - * singleton key, null otherwise. - */ - public Object get(Object key) - { - return equals(key, k) ? v : null; - } - - /** - * Calculate the hashcode directly. - * - * @return The hashcode computed from the singleton key - * and the singleton value. - */ - public int hashCode() - { - return hashCode(k) ^ hashCode(v); - } - - /** - * Return the keyset. - * - * @return A singleton containing the key. - */ - public Set keySet() - { - if (keys == null) - keys = singleton(k); - return keys; - } - - /** - * The size: always 1! - * - * @return 1. - */ - public int size() - { - return 1; - } - - /** - * Return the values. Technically, a singleton, while more specific than - * a general Collection, will work. Besides, that's what the JDK uses! - * - * @return A singleton containing the value. - */ - public Collection values() - { - if (values == null) - values = singleton(v); - return values; - } - - /** - * Obvious string. - * - * @return A string containing the string representations of the key - * and its associated value. - */ - public String toString() - { - return "{" + k + "=" + v + "}"; - } - } // class SingletonMap - - /** - * Sort a list according to the natural ordering of its elements. The list - * must be modifiable, but can be of fixed size. The sort algorithm is - * precisely that used by Arrays.sort(Object[]), which offers guaranteed - * nlog(n) performance. This implementation dumps the list into an array, - * sorts the array, and then iterates over the list setting each element from - * the array. - * - * @param l the List to sort - * @throws ClassCastException if some items are not mutually comparable - * @throws UnsupportedOperationException if the List is not modifiable - * @throws NullPointerException if some element is null - * @see Arrays#sort(Object[]) - */ - public static void sort(List l) - { - sort(l, null); - } - - /** - * Sort a list according to a specified Comparator. The list must be - * modifiable, but can be of fixed size. The sort algorithm is precisely that - * used by Arrays.sort(Object[], Comparator), which offers guaranteed - * nlog(n) performance. This implementation dumps the list into an array, - * sorts the array, and then iterates over the list setting each element from - * the array. - * - * @param l the List to sort - * @param c the Comparator specifying the ordering for the elements, or - * null for natural ordering - * @throws ClassCastException if c will not compare some pair of items - * @throws UnsupportedOperationException if the List is not modifiable - * @throws NullPointerException if null is compared by natural ordering - * (only possible when c is null) - * @see Arrays#sort(Object[], Comparator) - */ - public static void sort(List l, Comparator c) - { - Object[] a = l.toArray(); - Arrays.sort(a, c); - ListIterator i = l.listIterator(); - for (int pos = 0, alen = a.length; pos < alen; pos++) - { - i.next(); - i.set(a[pos]); - } - } - - /** - * Swaps the elements at the specified positions within the list. Equal - * positions have no effect. - * - * @param l the list to work on - * @param i the first index to swap - * @param j the second index - * @throws UnsupportedOperationException if list.set is not supported - * @throws IndexOutOfBoundsException if either i or j is < 0 or >= - * list.size() - * @since 1.4 - */ - public static void swap(List l, int i, int j) - { - l.set(i, l.set(j, l.get(i))); - } - - - /** - * Returns a synchronized (thread-safe) collection wrapper backed by the - * given collection. Notice that element access through the iterators - * is thread-safe, but if the collection can be structurally modified - * (adding or removing elements) then you should synchronize around the - * iteration to avoid non-deterministic behavior:<br> - * <pre> - * Collection c = Collections.synchronizedCollection(new Collection(...)); - * ... - * synchronized (c) - * { - * Iterator i = c.iterator(); - * while (i.hasNext()) - * foo(i.next()); - * } - * </pre><p> - * - * Since the collection might be a List or a Set, and those have incompatible - * equals and hashCode requirements, this relies on Object's implementation - * rather than passing those calls on to the wrapped collection. The returned - * Collection implements Serializable, but can only be serialized if - * the collection it wraps is likewise Serializable. - * - * @param c the collection to wrap - * @return a synchronized view of the collection - * @see Serializable - */ - public static Collection synchronizedCollection(Collection c) - { - return new SynchronizedCollection(c); - } - - /** - * The implementation of {@link #synchronizedCollection(Collection)}. This - * class name is required for compatibility with Sun's JDK serializability. - * Package visible, so that collections such as the one for - * Hashtable.values() can specify which object to synchronize on. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - static class SynchronizedCollection - implements Collection, Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 3053995032091335093L; - - /** - * The wrapped collection. Package visible for use by subclasses. - * @serial the real collection - */ - final Collection c; - - /** - * The object to synchronize on. When an instance is created via public - * methods, it will be this; but other uses like SynchronizedMap.values() - * must specify another mutex. Package visible for use by subclasses. - * @serial the lock - */ - final Object mutex; - - /** - * Wrap a given collection. - * @param c the collection to wrap - * @throws NullPointerException if c is null - */ - SynchronizedCollection(Collection c) - { - this.c = c; - mutex = this; - if (c == null) - throw new NullPointerException(); - } - - /** - * Called only by trusted code to specify the mutex as well as the - * collection. - * @param sync the mutex - * @param c the collection - */ - SynchronizedCollection(Object sync, Collection c) - { - this.c = c; - mutex = sync; - } - - /** - * Adds the object to the underlying collection, first - * obtaining a lock on the mutex. - * - * @param o The object to add. - * @return <code>true</code> if the collection was modified as a result - * of this action. - * @throws UnsupportedOperationException if this collection does not - * support the add operation. - * @throws ClassCastException if o cannot be added to this collection due - * to its type. - * @throws NullPointerException if o is null and this collection doesn't - * support the addition of null values. - * @throws IllegalArgumentException if o cannot be added to this - * collection for some other reason. - */ - public boolean add(Object o) - { - synchronized (mutex) - { - return c.add(o); - } - } - - /** - * Adds the objects in col to the underlying collection, first - * obtaining a lock on the mutex. - * - * @param col The collection to take the new objects from. - * @return <code>true</code> if the collection was modified as a result - * of this action. - * @throws UnsupportedOperationException if this collection does not - * support the addAll operation. - * @throws ClassCastException if some element of col cannot be added to this - * collection due to its type. - * @throws NullPointerException if some element of col is null and this - * collection does not support the addition of null values. - * @throws NullPointerException if col itself is null. - * @throws IllegalArgumentException if some element of col cannot be added - * to this collection for some other reason. - */ - public boolean addAll(Collection col) - { - synchronized (mutex) - { - return c.addAll(col); - } - } - - /** - * Removes all objects from the underlying collection, - * first obtaining a lock on the mutex. - * - * @throws UnsupportedOperationException if this collection does not - * support the clear operation. - */ - public void clear() - { - synchronized (mutex) - { - c.clear(); - } - } - - /** - * Checks for the existence of o within the underlying - * collection, first obtaining a lock on the mutex. - * - * @param o the element to look for. - * @return <code>true</code> if this collection contains at least one - * element e such that <code>o == null ? e == null : o.equals(e)</code>. - * @throws ClassCastException if the type of o is not a valid type for this - * collection. - * @throws NullPointerException if o is null and this collection doesn't - * support null values. - */ - public boolean contains(Object o) - { - synchronized (mutex) - { - return c.contains(o); - } - } - - /** - * Checks for the existence of each object in cl - * within the underlying collection, first obtaining - * a lock on the mutex. - * - * @param cl the collection to test for. - * @return <code>true</code> if for every element o in c, contains(o) - * would return <code>true</code>. - * @throws ClassCastException if the type of any element in cl is not a valid - * type for this collection. - * @throws NullPointerException if some element of cl is null and this - * collection does not support null values. - * @throws NullPointerException if cl itself is null. - */ - public boolean containsAll(Collection c1) - { - synchronized (mutex) - { - return c.containsAll(c1); - } - } - - /** - * Returns <code>true</code> if there are no objects in the underlying - * collection. A lock on the mutex is obtained before the - * check is performed. - * - * @return <code>true</code> if this collection contains no elements. - */ - public boolean isEmpty() - { - synchronized (mutex) - { - return c.isEmpty(); - } - } - - /** - * Returns a synchronized iterator wrapper around the underlying - * collection's iterator. A lock on the mutex is obtained before - * retrieving the collection's iterator. - * - * @return An iterator over the elements in the underlying collection, - * which returns each element in any order. - */ - public Iterator iterator() - { - synchronized (mutex) - { - return new SynchronizedIterator(mutex, c.iterator()); - } - } - - /** - * Removes the specified object from the underlying collection, - * first obtaining a lock on the mutex. - * - * @param o The object to remove. - * @return <code>true</code> if the collection changed as a result of this call, that is, - * if the collection contained at least one occurrence of o. - * @throws UnsupportedOperationException if this collection does not - * support the remove operation. - * @throws ClassCastException if the type of o is not a valid type - * for this collection. - * @throws NullPointerException if o is null and the collection doesn't - * support null values. - */ - public boolean remove(Object o) - { - synchronized (mutex) - { - return c.remove(o); - } - } - - /** - * Removes all elements, e, of the underlying - * collection for which <code>col.contains(e)</code> - * returns <code>true</code>. A lock on the mutex is obtained - * before the operation proceeds. - * - * @param col The collection of objects to be removed. - * @return <code>true</code> if this collection was modified as a result of this call. - * @throws UnsupportedOperationException if this collection does not - * support the removeAll operation. - * @throws ClassCastException if the type of any element in c is not a valid - * type for this collection. - * @throws NullPointerException if some element of c is null and this - * collection does not support removing null values. - * @throws NullPointerException if c itself is null. - */ - public boolean removeAll(Collection col) - { - synchronized (mutex) - { - return c.removeAll(col); - } - } - - /** - * Retains all elements, e, of the underlying - * collection for which <code>col.contains(e)</code> - * returns <code>true</code>. That is, every element that doesn't - * exist in col is removed. A lock on the mutex is obtained - * before the operation proceeds. - * - * @param col The collection of objects to be removed. - * @return <code>true</code> if this collection was modified as a result of this call. - * @throws UnsupportedOperationException if this collection does not - * support the removeAll operation. - * @throws ClassCastException if the type of any element in c is not a valid - * type for this collection. - * @throws NullPointerException if some element of c is null and this - * collection does not support removing null values. - * @throws NullPointerException if c itself is null. - */ - public boolean retainAll(Collection col) - { - synchronized (mutex) - { - return c.retainAll(col); - } - } - - /** - * Retrieves the size of the underlying collection. - * A lock on the mutex is obtained before the collection - * is accessed. - * - * @return The size of the collection. - */ - public int size() - { - synchronized (mutex) - { - return c.size(); - } - } - - /** - * Returns an array containing each object within the underlying - * collection. A lock is obtained on the mutex before the collection - * is accessed. - * - * @return An array of objects, matching the collection in size. The - * elements occur in any order. - */ - public Object[] toArray() - { - synchronized (mutex) - { - return c.toArray(); - } - } - - /** - * Copies the elements in the underlying collection to the supplied - * array. If <code>a.length < size()</code>, a new array of the - * same run-time type is created, with a size equal to that of - * the collection. If <code>a.length > size()</code>, then the - * elements from 0 to <code>size() - 1</code> contain the elements - * from this collection. The following element is set to null - * to indicate the end of the collection objects. However, this - * only makes a difference if null is not a permitted value within - * the collection. - * Before the copying takes place, a lock is obtained on the mutex. - * - * @param a An array to copy elements to. - * @return An array containing the elements of the underlying collection. - * @throws ArrayStoreException if the type of any element of the - * collection is not a subtype of the element type of a. - */ - public Object[] toArray(Object[] a) - { - synchronized (mutex) - { - return c.toArray(a); - } - } - - /** - * Returns a string representation of the underlying collection. - * A lock is obtained on the mutex before the string is created. - * - * @return A string representation of the collection. - */ - public String toString() - { - synchronized (mutex) - { - return c.toString(); - } - } - } // class SynchronizedCollection - - /** - * The implementation of the various iterator methods in the - * synchronized classes. These iterators must "sync" on the same object - * as the collection they iterate over. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class SynchronizedIterator implements Iterator - { - /** - * The object to synchronize on. Package visible for use by subclass. - */ - final Object mutex; - - /** - * The wrapped iterator. - */ - private final Iterator i; - - /** - * Only trusted code creates a wrapper, with the specified sync. - * @param sync the mutex - * @param i the wrapped iterator - */ - SynchronizedIterator(Object sync, Iterator i) - { - this.i = i; - mutex = sync; - } - - /** - * Retrieves the next object in the underlying collection. - * A lock is obtained on the mutex before the collection is accessed. - * - * @return The next object in the collection. - * @throws NoSuchElementException if there are no more elements - */ - public Object next() - { - synchronized (mutex) - { - return i.next(); - } - } - - /** - * Returns <code>true</code> if objects can still be retrieved from the iterator - * using <code>next()</code>. A lock is obtained on the mutex before - * the collection is accessed. - * - * @return <code>true</code> if at least one element is still to be returned by - * <code>next()</code>. - */ - public boolean hasNext() - { - synchronized (mutex) - { - return i.hasNext(); - } - } - - /** - * Removes the object that was last returned by <code>next()</code> - * from the underlying collection. Only one call to this method is - * allowed per call to the <code>next()</code> method, and it does - * not affect the value that will be returned by <code>next()</code>. - * Thus, if element n was retrieved from the collection by - * <code>next()</code>, it is this element that gets removed. - * Regardless of whether this takes place or not, element n+1 is - * still returned on the subsequent <code>next()</code> call. - * - * @throws IllegalStateException if next has not yet been called or remove - * has already been called since the last call to next. - * @throws UnsupportedOperationException if this Iterator does not support - * the remove operation. - */ - public void remove() - { - synchronized (mutex) - { - i.remove(); - } - } - } // class SynchronizedIterator - - /** - * Returns a synchronized (thread-safe) list wrapper backed by the - * given list. Notice that element access through the iterators - * is thread-safe, but if the list can be structurally modified - * (adding or removing elements) then you should synchronize around the - * iteration to avoid non-deterministic behavior:<br> - * <pre> - * List l = Collections.synchronizedList(new List(...)); - * ... - * synchronized (l) - * { - * Iterator i = l.iterator(); - * while (i.hasNext()) - * foo(i.next()); - * } - * </pre><p> - * - * The returned List implements Serializable, but can only be serialized if - * the list it wraps is likewise Serializable. In addition, if the wrapped - * list implements RandomAccess, this does too. - * - * @param l the list to wrap - * @return a synchronized view of the list - * @see Serializable - * @see RandomAccess - */ - public static List synchronizedList(List l) - { - if (l instanceof RandomAccess) - return new SynchronizedRandomAccessList(l); - return new SynchronizedList(l); - } - - /** - * The implementation of {@link #synchronizedList(List)} for sequential - * lists. This class name is required for compatibility with Sun's JDK - * serializability. Package visible, so that lists such as Vector.subList() - * can specify which object to synchronize on. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - static class SynchronizedList extends SynchronizedCollection - implements List - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -7754090372962971524L; - - /** - * The wrapped list; stored both here and in the superclass to avoid - * excessive casting. Package visible for use by subclass. - * @serial the wrapped list - */ - final List list; - - /** - * Wrap a given list. - * @param l the list to wrap - * @throws NullPointerException if l is null - */ - SynchronizedList(List l) - { - super(l); - list = l; - } - - /** - * Called only by trusted code to specify the mutex as well as the list. - * @param sync the mutex - * @param l the list - */ - SynchronizedList(Object sync, List l) - { - super(sync, l); - list = l; - } - - /** - * Insert an element into the underlying list at a given position (optional - * operation). This shifts all existing elements from that position to the - * end one index to the right. This version of add has no return, since it is - * assumed to always succeed if there is no exception. Before the - * addition takes place, a lock is obtained on the mutex. - * - * @param index the location to insert the item - * @param o the object to insert - * @throws UnsupportedOperationException if this list does not support the - * add operation - * @throws IndexOutOfBoundsException if index < 0 || index > size() - * @throws ClassCastException if o cannot be added to this list due to its - * type - * @throws IllegalArgumentException if o cannot be added to this list for - * some other reason - * @throws NullPointerException if o is null and this list doesn't support - * the addition of null values. - */ - public void add(int index, Object o) - { - synchronized (mutex) - { - list.add(index, o); - } - } - - /** - * Add an element to the end of the underlying list (optional operation). - * If the list imposes restraints on what can be inserted, such as no null - * elements, this should be documented. A lock is obtained on the mutex before - * any of the elements are added. - * - * @param o the object to add - * @return <code>true</code>, as defined by Collection for a modified list - * @throws UnsupportedOperationException if this list does not support the - * add operation - * @throws ClassCastException if o cannot be added to this list due to its - * type - * @throws IllegalArgumentException if o cannot be added to this list for - * some other reason - * @throws NullPointerException if o is null and this list doesn't support - * the addition of null values. - */ - public boolean addAll(int index, Collection c) - { - synchronized (mutex) - { - return list.addAll(index, c); - } - } - - /** - * Tests whether the underlying list is equal to the supplied object. - * The object is deemed to be equal if it is also a <code>List</code> - * of equal size and with the same elements (i.e. each element, e1, - * in list, l1, and each element, e2, in l2, must return <code>true</code> for - * <code>e1 == null ? e2 == null : e1.equals(e2)</code>. Before the - * comparison is made, a lock is obtained on the mutex. - * - * @param o The object to test for equality with the underlying list. - * @return <code>true</code> if o is equal to the underlying list under the above - * definition. - */ - public boolean equals(Object o) - { - synchronized (mutex) - { - return list.equals(o); - } - } - - /** - * Retrieves the object at the specified index. A lock - * is obtained on the mutex before the list is accessed. - * - * @param index the index of the element to be returned - * @return the element at index index in this list - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - public Object get(int index) - { - synchronized (mutex) - { - return list.get(index); - } - } - - /** - * Obtains a hashcode for the underlying list, first obtaining - * a lock on the mutex. The calculation of the hashcode is - * detailed in the documentation for the <code>List</code> - * interface. - * - * @return The hashcode of the underlying list. - * @see List#hashCode() - */ - public int hashCode() - { - synchronized (mutex) - { - return list.hashCode(); - } - } - - /** - * Obtain the first index at which a given object is to be found in the - * underlying list. A lock is obtained on the mutex before the list is - * accessed. - * - * @param o the object to search for - * @return the least integer n such that <code>o == null ? get(n) == null : - * o.equals(get(n))</code>, or -1 if there is no such index. - * @throws ClassCastException if the type of o is not a valid - * type for this list. - * @throws NullPointerException if o is null and this - * list does not support null values. - */ - - public int indexOf(Object o) - { - synchronized (mutex) - { - return list.indexOf(o); - } - } - - /** - * Obtain the last index at which a given object is to be found in this - * underlying list. A lock is obtained on the mutex before the list - * is accessed. - * - * @return the greatest integer n such that <code>o == null ? get(n) == null - * : o.equals(get(n))</code>, or -1 if there is no such index. - * @throws ClassCastException if the type of o is not a valid - * type for this list. - * @throws NullPointerException if o is null and this - * list does not support null values. - */ - public int lastIndexOf(Object o) - { - synchronized (mutex) - { - return list.lastIndexOf(o); - } - } - - /** - * Retrieves a synchronized wrapper around the underlying list's - * list iterator. A lock is obtained on the mutex before the - * list iterator is retrieved. - * - * @return A list iterator over the elements in the underlying list. - * The list iterator allows additional list-specific operations - * to be performed, in addition to those supplied by the - * standard iterator. - */ - public ListIterator listIterator() - { - synchronized (mutex) - { - return new SynchronizedListIterator(mutex, list.listIterator()); - } - } - - /** - * Retrieves a synchronized wrapper around the underlying list's - * list iterator. A lock is obtained on the mutex before the - * list iterator is retrieved. The iterator starts at the - * index supplied, leading to the element at that index being - * the first one returned by <code>next()</code>. Calling - * <code>previous()</code> from this initial position returns - * index - 1. - * - * @param index the position, between 0 and size() inclusive, to begin the - * iteration from - * @return A list iterator over the elements in the underlying list. - * The list iterator allows additional list-specific operations - * to be performed, in addition to those supplied by the - * standard iterator. - * @throws IndexOutOfBoundsException if index < 0 || index > size() - */ - public ListIterator listIterator(int index) - { - synchronized (mutex) - { - return new SynchronizedListIterator(mutex, list.listIterator(index)); - } - } - - /** - * Remove the element at a given position in the underlying list (optional - * operation). All remaining elements are shifted to the left to fill the gap. - * A lock on the mutex is obtained before the element is removed. - * - * @param index the position within the list of the object to remove - * @return the object that was removed - * @throws UnsupportedOperationException if this list does not support the - * remove operation - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - public Object remove(int index) - { - synchronized (mutex) - { - return list.remove(index); - } - } - - /** - * Replace an element of the underlying list with another object (optional - * operation). A lock is obtained on the mutex before the element is - * replaced. - * - * @param index the position within this list of the element to be replaced - * @param o the object to replace it with - * @return the object that was replaced - * @throws UnsupportedOperationException if this list does not support the - * set operation. - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - * @throws ClassCastException if o cannot be added to this list due to its - * type - * @throws IllegalArgumentException if o cannot be added to this list for - * some other reason - * @throws NullPointerException if o is null and this - * list does not support null values. - */ - public Object set(int index, Object o) - { - synchronized (mutex) - { - return list.set(index, o); - } - } - - /** - * Obtain a List view of a subsection of the underlying list, from fromIndex - * (inclusive) to toIndex (exclusive). If the two indices are equal, the - * sublist is empty. The returned list should be modifiable if and only - * if this list is modifiable. Changes to the returned list should be - * reflected in this list. If this list is structurally modified in - * any way other than through the returned list, the result of any subsequent - * operations on the returned list is undefined. A lock is obtained - * on the mutex before the creation of the sublist. The returned list - * is also synchronized, using the same mutex. - * - * @param fromIndex the index that the returned list should start from - * (inclusive) - * @param toIndex the index that the returned list should go to (exclusive) - * @return a List backed by a subsection of this list - * @throws IndexOutOfBoundsException if fromIndex < 0 - * || toIndex > size() || fromIndex > toIndex - */ - public List subList(int fromIndex, int toIndex) - { - synchronized (mutex) - { - return new SynchronizedList(mutex, list.subList(fromIndex, toIndex)); - } - } - } // class SynchronizedList - - /** - * The implementation of {@link #synchronizedList(List)} for random-access - * lists. This class name is required for compatibility with Sun's JDK - * serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class SynchronizedRandomAccessList - extends SynchronizedList implements RandomAccess - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 1530674583602358482L; - - /** - * Wrap a given list. - * @param l the list to wrap - * @throws NullPointerException if l is null - */ - SynchronizedRandomAccessList(List l) - { - super(l); - } - - /** - * Called only by trusted code to specify the mutex as well as the - * collection. - * @param sync the mutex - * @param l the list - */ - SynchronizedRandomAccessList(Object sync, List l) - { - super(sync, l); - } - - /** - * Obtain a List view of a subsection of the underlying list, from fromIndex - * (inclusive) to toIndex (exclusive). If the two indices are equal, the - * sublist is empty. The returned list should be modifiable if and only - * if this list is modifiable. Changes to the returned list should be - * reflected in this list. If this list is structurally modified in - * any way other than through the returned list, the result of any subsequent - * operations on the returned list is undefined. A lock is obtained - * on the mutex before the creation of the sublist. The returned list - * is also synchronized, using the same mutex. Random accessibility - * is also extended to the new list. - * - * @param fromIndex the index that the returned list should start from - * (inclusive) - * @param toIndex the index that the returned list should go to (exclusive) - * @return a List backed by a subsection of this list - * @throws IndexOutOfBoundsException if fromIndex < 0 - * || toIndex > size() || fromIndex > toIndex - */ - public List subList(int fromIndex, int toIndex) - { - synchronized (mutex) - { - return new SynchronizedRandomAccessList(mutex, - list.subList(fromIndex, - toIndex)); - } - } - } // class SynchronizedRandomAccessList - - /** - * The implementation of {@link SynchronizedList#listIterator()}. This - * iterator must "sync" on the same object as the list it iterates over. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class SynchronizedListIterator - extends SynchronizedIterator implements ListIterator - { - /** - * The wrapped iterator, stored both here and in the superclass to - * avoid excessive casting. - */ - private final ListIterator li; - - /** - * Only trusted code creates a wrapper, with the specified sync. - * @param sync the mutex - * @param li the wrapped iterator - */ - SynchronizedListIterator(Object sync, ListIterator li) - { - super(sync, li); - this.li = li; - } - - /** - * Insert an element into the underlying list at the current position of - * the iterator (optional operation). The element is inserted in between - * the element that would be returned by <code>previous()</code> and the - * element that would be returned by <code>next()</code>. After the - * insertion, a subsequent call to next is unaffected, but - * a call to previous returns the item that was added. The values returned - * by nextIndex() and previousIndex() are incremented. A lock is obtained - * on the mutex before the addition takes place. - * - * @param o the object to insert into the list - * @throws ClassCastException if the object is of a type which cannot be added - * to this list. - * @throws IllegalArgumentException if some other aspect of the object stops - * it being added to this list. - * @throws UnsupportedOperationException if this ListIterator does not - * support the add operation. - */ - public void add(Object o) - { - synchronized (mutex) - { - li.add(o); - } - } - - /** - * Tests whether there are elements remaining in the underlying list - * in the reverse direction. In other words, <code>previous()</code> - * will not fail with a NoSuchElementException. A lock is obtained - * on the mutex before the check takes place. - * - * @return <code>true</code> if the list continues in the reverse direction - */ - public boolean hasPrevious() - { - synchronized (mutex) - { - return li.hasPrevious(); - } - } - - /** - * Find the index of the element that would be returned by a call to - * <code>next()</code>. If hasNext() returns <code>false</code>, this - * returns the list size. A lock is obtained on the mutex before the - * query takes place. - * - * @return the index of the element that would be returned by next() - */ - public int nextIndex() - { - synchronized (mutex) - { - return li.nextIndex(); - } - } - - /** - * Obtain the previous element from the underlying list. Repeated - * calls to previous may be used to iterate backwards over the entire list, - * or calls to next and previous may be used together to go forwards and - * backwards. Alternating calls to next and previous will return the same - * element. A lock is obtained on the mutex before the object is retrieved. - * - * @return the next element in the list in the reverse direction - * @throws NoSuchElementException if there are no more elements - */ - public Object previous() - { - synchronized (mutex) - { - return li.previous(); - } - } - - /** - * Find the index of the element that would be returned by a call to - * previous. If hasPrevious() returns <code>false</code>, this returns -1. - * A lock is obtained on the mutex before the query takes place. - * - * @return the index of the element that would be returned by previous() - */ - public int previousIndex() - { - synchronized (mutex) - { - return li.previousIndex(); - } - } - - /** - * Replace the element last returned by a call to <code>next()</code> or - * <code>previous()</code> with a given object (optional operation). This - * method may only be called if neither <code>add()</code> nor - * <code>remove()</code> have been called since the last call to - * <code>next()</code> or <code>previous</code>. A lock is obtained - * on the mutex before the list is modified. - * - * @param o the object to replace the element with - * @throws ClassCastException the object is of a type which cannot be added - * to this list - * @throws IllegalArgumentException some other aspect of the object stops - * it being added to this list - * @throws IllegalStateException if neither next or previous have been - * called, or if add or remove has been called since the last call - * to next or previous - * @throws UnsupportedOperationException if this ListIterator does not - * support the set operation - */ - public void set(Object o) - { - synchronized (mutex) - { - li.set(o); - } - } - } // class SynchronizedListIterator - - /** - * Returns a synchronized (thread-safe) map wrapper backed by the given - * map. Notice that element access through the collection views and their - * iterators are thread-safe, but if the map can be structurally modified - * (adding or removing elements) then you should synchronize around the - * iteration to avoid non-deterministic behavior:<br> - * <pre> - * Map m = Collections.synchronizedMap(new Map(...)); - * ... - * Set s = m.keySet(); // safe outside a synchronized block - * synchronized (m) // synch on m, not s - * { - * Iterator i = s.iterator(); - * while (i.hasNext()) - * foo(i.next()); - * } - * </pre><p> - * - * The returned Map implements Serializable, but can only be serialized if - * the map it wraps is likewise Serializable. - * - * @param m the map to wrap - * @return a synchronized view of the map - * @see Serializable - */ - public static Map synchronizedMap(Map m) - { - return new SynchronizedMap(m); - } - - /** - * The implementation of {@link #synchronizedMap(Map)}. This - * class name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class SynchronizedMap implements Map, Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 1978198479659022715L; - - /** - * The wrapped map. - * @serial the real map - */ - private final Map m; - - /** - * The object to synchronize on. When an instance is created via public - * methods, it will be this; but other uses like - * SynchronizedSortedMap.subMap() must specify another mutex. Package - * visible for use by subclass. - * @serial the lock - */ - final Object mutex; - - /** - * Cache the entry set. - */ - private transient Set entries; - - /** - * Cache the key set. - */ - private transient Set keys; - - /** - * Cache the value collection. - */ - private transient Collection values; - - /** - * Wrap a given map. - * @param m the map to wrap - * @throws NullPointerException if m is null - */ - SynchronizedMap(Map m) - { - this.m = m; - mutex = this; - if (m == null) - throw new NullPointerException(); - } - - /** - * Called only by trusted code to specify the mutex as well as the map. - * @param sync the mutex - * @param m the map - */ - SynchronizedMap(Object sync, Map m) - { - this.m = m; - mutex = sync; - } - - /** - * Clears all the entries from the underlying map. A lock is obtained - * on the mutex before the map is cleared. - * - * @throws UnsupportedOperationException if clear is not supported - */ - public void clear() - { - synchronized (mutex) - { - m.clear(); - } - } - - /** - * Returns <code>true</code> if the underlying map contains a entry for the given key. - * A lock is obtained on the mutex before the map is queried. - * - * @param key the key to search for. - * @return <code>true</code> if the underlying map contains the key. - * @throws ClassCastException if the key is of an inappropriate type. - * @throws NullPointerException if key is <code>null</code> but the map - * does not permit null keys. - */ - public boolean containsKey(Object key) - { - synchronized (mutex) - { - return m.containsKey(key); - } - } - - /** - * Returns <code>true</code> if the underlying map contains at least one entry with the - * given value. In other words, returns <code>true</code> if a value v exists where - * <code>(value == null ? v == null : value.equals(v))</code>. This usually - * requires linear time. A lock is obtained on the mutex before the map - * is queried. - * - * @param value the value to search for - * @return <code>true</code> if the map contains the value - * @throws ClassCastException if the type of the value is not a valid type - * for this map. - * @throws NullPointerException if the value is null and the map doesn't - * support null values. - */ - public boolean containsValue(Object value) - { - synchronized (mutex) - { - return m.containsValue(value); - } - } - - // This is one of the ickiest cases of nesting I've ever seen. It just - // means "return a SynchronizedSet, except that the iterator() method - // returns an SynchronizedIterator whose next() method returns a - // synchronized wrapper around its normal return value". - public Set entrySet() - { - // Define this here to spare some nesting. - class SynchronizedMapEntry implements Map.Entry - { - final Map.Entry e; - SynchronizedMapEntry(Object o) - { - e = (Map.Entry) o; - } - - /** - * Returns <code>true</code> if the object, o, implements <code>Map.Entry</code> - * with the same key and value as the underlying entry. A lock is - * obtained on the mutex before the comparison takes place. - * - * @param o The object to compare with this entry. - * @return <code>true</code> if o is equivalent to the underlying map entry. - */ - public boolean equals(Object o) - { - synchronized (mutex) - { - return e.equals(o); - } - } - - /** - * Returns the key used in the underlying map entry. A lock is obtained - * on the mutex before the key is retrieved. - * - * @return The key of the underlying map entry. - */ - public Object getKey() - { - synchronized (mutex) - { - return e.getKey(); - } - } - - /** - * Returns the value used in the underlying map entry. A lock is obtained - * on the mutex before the value is retrieved. - * - * @return The value of the underlying map entry. - */ - public Object getValue() - { - synchronized (mutex) - { - return e.getValue(); - } - } - - /** - * Computes the hash code for the underlying map entry. - * This computation is described in the documentation for the - * <code>Map</code> interface. A lock is obtained on the mutex - * before the underlying map is accessed. - * - * @return The hash code of the underlying map entry. - * @see Map#hashCode() - */ - public int hashCode() - { - synchronized (mutex) - { - return e.hashCode(); - } - } - - /** - * Replaces the value in the underlying map entry with the specified - * object (optional operation). A lock is obtained on the mutex - * before the map is altered. The map entry, in turn, will alter - * the underlying map object. The operation is undefined if the - * <code>remove()</code> method of the iterator has been called - * beforehand. - * - * @param value the new value to store - * @return the old value - * @throws UnsupportedOperationException if the operation is not supported. - * @throws ClassCastException if the value is of the wrong type. - * @throws IllegalArgumentException if something about the value - * prevents it from existing in this map. - * @throws NullPointerException if the map forbids null values. - */ - public Object setValue(Object value) - { - synchronized (mutex) - { - return e.setValue(value); - } - } - - /** - * Returns a textual representation of the underlying map entry. - * A lock is obtained on the mutex before the entry is accessed. - * - * @return The contents of the map entry in <code>String</code> form. - */ - public String toString() - { - synchronized (mutex) - { - return e.toString(); - } - } - } // class SynchronizedMapEntry - - // Now the actual code. - if (entries == null) - synchronized (mutex) - { - entries = new SynchronizedSet(mutex, m.entrySet()) - { - /** - * Returns an iterator over the set. The iterator has no specific order, - * unless further specified. A lock is obtained on the set's mutex - * before the iterator is created. The created iterator is also - * thread-safe. - * - * @return A synchronized set iterator. - */ - public Iterator iterator() - { - synchronized (super.mutex) - { - return new SynchronizedIterator(super.mutex, c.iterator()) - { - /** - * Retrieves the next map entry from the iterator. - * A lock is obtained on the iterator's mutex before - * the entry is created. The new map entry is enclosed in - * a thread-safe wrapper. - * - * @return A synchronized map entry. - */ - public Object next() - { - synchronized (super.mutex) - { - return new SynchronizedMapEntry(super.next()); - } - } - }; - } - } - }; - } - return entries; - } - - /** - * Returns <code>true</code> if the object, o, is also an instance - * of <code>Map</code> and contains an equivalent - * entry set to that of the underlying map. A lock - * is obtained on the mutex before the objects are - * compared. - * - * @param o The object to compare. - * @return <code>true</code> if o and the underlying map are equivalent. - */ - public boolean equals(Object o) - { - synchronized (mutex) - { - return m.equals(o); - } - } - - /** - * Returns the value associated with the given key, or null - * if no such mapping exists. An ambiguity exists with maps - * that accept null values as a return value of null could - * be due to a non-existent mapping or simply a null value - * for that key. To resolve this, <code>containsKey</code> - * should be used. A lock is obtained on the mutex before - * the value is retrieved from the underlying map. - * - * @param key The key of the required mapping. - * @return The value associated with the given key, or - * null if no such mapping exists. - * @throws ClassCastException if the key is an inappropriate type. - * @throws NullPointerException if this map does not accept null keys. - */ - public Object get(Object key) - { - synchronized (mutex) - { - return m.get(key); - } - } - - /** - * Calculates the hash code of the underlying map as the - * sum of the hash codes of all entries. A lock is obtained - * on the mutex before the hash code is computed. - * - * @return The hash code of the underlying map. - */ - public int hashCode() - { - synchronized (mutex) - { - return m.hashCode(); - } - } - - /** - * Returns <code>true</code> if the underlying map contains no entries. - * A lock is obtained on the mutex before the map is examined. - * - * @return <code>true</code> if the map is empty. - */ - public boolean isEmpty() - { - synchronized (mutex) - { - return m.isEmpty(); - } - } - - /** - * Returns a thread-safe set view of the keys in the underlying map. The - * set is backed by the map, so that changes in one show up in the other. - * Modifications made while an iterator is in progress cause undefined - * behavior. If the set supports removal, these methods remove the - * underlying mapping from the map: <code>Iterator.remove</code>, - * <code>Set.remove</code>, <code>removeAll</code>, <code>retainAll</code>, - * and <code>clear</code>. Element addition, via <code>add</code> or - * <code>addAll</code>, is not supported via this set. A lock is obtained - * on the mutex before the set is created. - * - * @return A synchronized set containing the keys of the underlying map. - */ - public Set keySet() - { - if (keys == null) - synchronized (mutex) - { - keys = new SynchronizedSet(mutex, m.keySet()); - } - return keys; - } - - /** - * Associates the given key to the given value (optional operation). If the - * underlying map already contains the key, its value is replaced. Be aware - * that in a map that permits <code>null</code> values, a null return does not - * always imply that the mapping was created. A lock is obtained on the mutex - * before the modification is made. - * - * @param key the key to map. - * @param value the value to be mapped. - * @return the previous value of the key, or null if there was no mapping - * @throws UnsupportedOperationException if the operation is not supported - * @throws ClassCastException if the key or value is of the wrong type - * @throws IllegalArgumentException if something about this key or value - * prevents it from existing in this map - * @throws NullPointerException if either the key or the value is null, - * and the map forbids null keys or values - * @see #containsKey(Object) - */ - public Object put(Object key, Object value) - { - synchronized (mutex) - { - return m.put(key, value); - } - } - - /** - * Copies all entries of the given map to the underlying one (optional - * operation). If the map already contains a key, its value is replaced. - * A lock is obtained on the mutex before the operation proceeds. - * - * @param m the mapping to load into this map - * @throws UnsupportedOperationException if the operation is not supported - * @throws ClassCastException if a key or value is of the wrong type - * @throws IllegalArgumentException if something about a key or value - * prevents it from existing in this map - * @throws NullPointerException if the map forbids null keys or values, or - * if <code>m</code> is null. - * @see #put(Object, Object) - */ - public void putAll(Map map) - { - synchronized (mutex) - { - m.putAll(map); - } - } - - /** - * Removes the mapping for the key, o, if present (optional operation). If - * the key is not present, this returns null. Note that maps which permit - * null values may also return null if the key was removed. A prior - * <code>containsKey()</code> check is required to avoid this ambiguity. - * Before the mapping is removed, a lock is obtained on the mutex. - * - * @param key the key to remove - * @return the value the key mapped to, or null if not present - * @throws UnsupportedOperationException if deletion is unsupported - * @throws NullPointerException if the key is null and this map doesn't - * support null keys. - * @throws ClassCastException if the type of the key is not a valid type - * for this map. - */ - public Object remove(Object o) - { - synchronized (mutex) - { - return m.remove(o); - } - } - - /** - * Retrieves the size of the underlying map. A lock - * is obtained on the mutex before access takes place. - * Maps with a size greater than <code>Integer.MAX_VALUE</code> - * return <code>Integer.MAX_VALUE</code> instead. - * - * @return The size of the underlying map. - */ - public int size() - { - synchronized (mutex) - { - return m.size(); - } - } - - /** - * Returns a textual representation of the underlying - * map. A lock is obtained on the mutex before the map - * is accessed. - * - * @return The map in <code>String</code> form. - */ - public String toString() - { - synchronized (mutex) - { - return m.toString(); - } - } - - /** - * Returns a synchronized collection view of the values in the underlying - * map. The collection is backed by the map, so that changes in one show up in - * the other. Modifications made while an iterator is in progress cause - * undefined behavior. If the collection supports removal, these methods - * remove the underlying mapping from the map: <code>Iterator.remove</code>, - * <code>Collection.remove</code>, <code>removeAll</code>, - * <code>retainAll</code>, and <code>clear</code>. Element addition, via - * <code>add</code> or <code>addAll</code>, is not supported via this - * collection. A lock is obtained on the mutex before the collection - * is created. - * - * @return the collection of all values in the underlying map. - */ - public Collection values() - { - if (values == null) - synchronized (mutex) - { - values = new SynchronizedCollection(mutex, m.values()); - } - return values; - } - } // class SynchronizedMap - - /** - * Returns a synchronized (thread-safe) set wrapper backed by the given - * set. Notice that element access through the iterator is thread-safe, but - * if the set can be structurally modified (adding or removing elements) - * then you should synchronize around the iteration to avoid - * non-deterministic behavior:<br> - * <pre> - * Set s = Collections.synchronizedSet(new Set(...)); - * ... - * synchronized (s) - * { - * Iterator i = s.iterator(); - * while (i.hasNext()) - * foo(i.next()); - * } - * </pre><p> - * - * The returned Set implements Serializable, but can only be serialized if - * the set it wraps is likewise Serializable. - * - * @param s the set to wrap - * @return a synchronized view of the set - * @see Serializable - */ - public static Set synchronizedSet(Set s) - { - return new SynchronizedSet(s); - } - - /** - * The implementation of {@link #synchronizedSet(Set)}. This class - * name is required for compatibility with Sun's JDK serializability. - * Package visible, so that sets such as Hashtable.keySet() - * can specify which object to synchronize on. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - static class SynchronizedSet extends SynchronizedCollection - implements Set - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 487447009682186044L; - - /** - * Wrap a given set. - * @param s the set to wrap - * @throws NullPointerException if s is null - */ - SynchronizedSet(Set s) - { - super(s); - } - - /** - * Called only by trusted code to specify the mutex as well as the set. - * @param sync the mutex - * @param s the set - */ - SynchronizedSet(Object sync, Set s) - { - super(sync, s); - } - - /** - * Returns <code>true</code> if the object, o, is a <code>Set</code> - * of the same size as the underlying set, and contains - * each element, e, which occurs in the underlying set. - * A lock is obtained on the mutex before the comparison - * takes place. - * - * @param o The object to compare against. - * @return <code>true</code> if o is an equivalent set. - */ - public boolean equals(Object o) - { - synchronized (mutex) - { - return c.equals(o); - } - } - - /** - * Computes the hash code for the underlying set as the - * sum of the hash code of all elements within the set. - * A lock is obtained on the mutex before the computation - * occurs. - * - * @return The hash code for the underlying set. - */ - public int hashCode() - { - synchronized (mutex) - { - return c.hashCode(); - } - } - } // class SynchronizedSet - - /** - * Returns a synchronized (thread-safe) sorted map wrapper backed by the - * given map. Notice that element access through the collection views, - * subviews, and their iterators are thread-safe, but if the map can be - * structurally modified (adding or removing elements) then you should - * synchronize around the iteration to avoid non-deterministic behavior:<br> - * <pre> - * SortedMap m = Collections.synchronizedSortedMap(new SortedMap(...)); - * ... - * Set s = m.keySet(); // safe outside a synchronized block - * SortedMap m2 = m.headMap(foo); // safe outside a synchronized block - * Set s2 = m2.keySet(); // safe outside a synchronized block - * synchronized (m) // synch on m, not m2, s or s2 - * { - * Iterator i = s.iterator(); - * while (i.hasNext()) - * foo(i.next()); - * i = s2.iterator(); - * while (i.hasNext()) - * bar(i.next()); - * } - * </pre><p> - * - * The returned SortedMap implements Serializable, but can only be - * serialized if the map it wraps is likewise Serializable. - * - * @param m the sorted map to wrap - * @return a synchronized view of the sorted map - * @see Serializable - */ - public static SortedMap synchronizedSortedMap(SortedMap m) - { - return new SynchronizedSortedMap(m); - } - - /** - * The implementation of {@link #synchronizedSortedMap(SortedMap)}. This - * class name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class SynchronizedSortedMap extends SynchronizedMap - implements SortedMap - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -8798146769416483793L; - - /** - * The wrapped map; stored both here and in the superclass to avoid - * excessive casting. - * @serial the wrapped map - */ - private final SortedMap sm; - - /** - * Wrap a given map. - * @param sm the map to wrap - * @throws NullPointerException if sm is null - */ - SynchronizedSortedMap(SortedMap sm) - { - super(sm); - this.sm = sm; - } - - /** - * Called only by trusted code to specify the mutex as well as the map. - * @param sync the mutex - * @param sm the map - */ - SynchronizedSortedMap(Object sync, SortedMap sm) - { - super(sync, sm); - this.sm = sm; - } - - /** - * Returns the comparator used in sorting the underlying map, or null if - * it is the keys' natural ordering. A lock is obtained on the mutex - * before the comparator is retrieved. - * - * @return the sorting comparator. - */ - public Comparator comparator() - { - synchronized (mutex) - { - return sm.comparator(); - } - } - - /** - * Returns the first, lowest sorted, key from the underlying map. - * A lock is obtained on the mutex before the map is accessed. - * - * @return the first key. - * @throws NoSuchElementException if this map is empty. - */ - public Object firstKey() - { - synchronized (mutex) - { - return sm.firstKey(); - } - } - - /** - * Returns a submap containing the keys from the first - * key (as returned by <code>firstKey()</code>) to - * the key before that specified. The submap supports all - * operations supported by the underlying map and all actions - * taking place on the submap are also reflected in the underlying - * map. A lock is obtained on the mutex prior to submap creation. - * This operation is equivalent to <code>subMap(firstKey(), toKey)</code>. - * The submap retains the thread-safe status of this map. - * - * @param toKey the exclusive upper range of the submap. - * @return a submap from <code>firstKey()</code> to the - * the key preceding toKey. - * @throws ClassCastException if toKey is not comparable to the underlying - * map's contents. - * @throws IllegalArgumentException if toKey is outside the map's range. - * @throws NullPointerException if toKey is null. but the map does not allow - * null keys. - */ - public SortedMap headMap(Object toKey) - { - synchronized (mutex) - { - return new SynchronizedSortedMap(mutex, sm.headMap(toKey)); - } - } - - /** - * Returns the last, highest sorted, key from the underlying map. - * A lock is obtained on the mutex before the map is accessed. - * - * @return the last key. - * @throws NoSuchElementException if this map is empty. - */ - public Object lastKey() - { - synchronized (mutex) - { - return sm.lastKey(); - } - } - - /** - * Returns a submap containing the keys from fromKey to - * the key before toKey. The submap supports all - * operations supported by the underlying map and all actions - * taking place on the submap are also reflected in the underlying - * map. A lock is obtained on the mutex prior to submap creation. - * The submap retains the thread-safe status of this map. - * - * @param fromKey the inclusive lower range of the submap. - * @param toKey the exclusive upper range of the submap. - * @return a submap from fromKey to the key preceding toKey. - * @throws ClassCastException if fromKey or toKey is not comparable - * to the underlying map's contents. - * @throws IllegalArgumentException if fromKey or toKey is outside the map's - * range. - * @throws NullPointerException if fromKey or toKey is null. but the map does - * not allow null keys. - */ - public SortedMap subMap(Object fromKey, Object toKey) - { - synchronized (mutex) - { - return new SynchronizedSortedMap(mutex, sm.subMap(fromKey, toKey)); - } - } - - /** - * Returns a submap containing all the keys from fromKey onwards. - * The submap supports all operations supported by the underlying - * map and all actions taking place on the submap are also reflected - * in the underlying map. A lock is obtained on the mutex prior to - * submap creation. The submap retains the thread-safe status of - * this map. - * - * @param fromKey the inclusive lower range of the submap. - * @return a submap from fromKey to <code>lastKey()</code>. - * @throws ClassCastException if fromKey is not comparable to the underlying - * map's contents. - * @throws IllegalArgumentException if fromKey is outside the map's range. - * @throws NullPointerException if fromKey is null. but the map does not allow - * null keys. - */ - public SortedMap tailMap(Object fromKey) - { - synchronized (mutex) - { - return new SynchronizedSortedMap(mutex, sm.tailMap(fromKey)); - } - } - } // class SynchronizedSortedMap - - /** - * Returns a synchronized (thread-safe) sorted set wrapper backed by the - * given set. Notice that element access through the iterator and through - * subviews are thread-safe, but if the set can be structurally modified - * (adding or removing elements) then you should synchronize around the - * iteration to avoid non-deterministic behavior:<br> - * <pre> - * SortedSet s = Collections.synchronizedSortedSet(new SortedSet(...)); - * ... - * SortedSet s2 = s.headSet(foo); // safe outside a synchronized block - * synchronized (s) // synch on s, not s2 - * { - * Iterator i = s2.iterator(); - * while (i.hasNext()) - * foo(i.next()); - * } - * </pre><p> - * - * The returned SortedSet implements Serializable, but can only be - * serialized if the set it wraps is likewise Serializable. - * - * @param s the sorted set to wrap - * @return a synchronized view of the sorted set - * @see Serializable - */ - public static SortedSet synchronizedSortedSet(SortedSet s) - { - return new SynchronizedSortedSet(s); - } - - /** - * The implementation of {@link #synchronizedSortedSet(SortedSet)}. This - * class name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class SynchronizedSortedSet extends SynchronizedSet - implements SortedSet - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 8695801310862127406L; - - /** - * The wrapped set; stored both here and in the superclass to avoid - * excessive casting. - * @serial the wrapped set - */ - private final SortedSet ss; - - /** - * Wrap a given set. - * @param ss the set to wrap - * @throws NullPointerException if ss is null - */ - SynchronizedSortedSet(SortedSet ss) - { - super(ss); - this.ss = ss; - } - - /** - * Called only by trusted code to specify the mutex as well as the set. - * @param sync the mutex - * @param l the list - */ - SynchronizedSortedSet(Object sync, SortedSet ss) - { - super(sync, ss); - this.ss = ss; - } - - /** - * Returns the comparator used in sorting the underlying set, or null if - * it is the elements' natural ordering. A lock is obtained on the mutex - * before the comparator is retrieved. - * - * @return the sorting comparator. - */ - public Comparator comparator() - { - synchronized (mutex) - { - return ss.comparator(); - } - } - - /** - * Returns the first, lowest sorted, element from the underlying set. - * A lock is obtained on the mutex before the set is accessed. - * - * @return the first element. - * @throws NoSuchElementException if this set is empty. - */ - public Object first() - { - synchronized (mutex) - { - return ss.first(); - } - } - - /** - * Returns a subset containing the element from the first - * element (as returned by <code>first()</code>) to - * the element before that specified. The subset supports all - * operations supported by the underlying set and all actions - * taking place on the subset are also reflected in the underlying - * set. A lock is obtained on the mutex prior to subset creation. - * This operation is equivalent to <code>subSet(first(), toElement)</code>. - * The subset retains the thread-safe status of this set. - * - * @param toElement the exclusive upper range of the subset. - * @return a subset from <code>first()</code> to the - * the element preceding toElement. - * @throws ClassCastException if toElement is not comparable to the underlying - * set's contents. - * @throws IllegalArgumentException if toElement is outside the set's range. - * @throws NullPointerException if toElement is null. but the set does not allow - * null elements. - */ - public SortedSet headSet(Object toElement) - { - synchronized (mutex) - { - return new SynchronizedSortedSet(mutex, ss.headSet(toElement)); - } - } - - /** - * Returns the last, highest sorted, element from the underlying set. - * A lock is obtained on the mutex before the set is accessed. - * - * @return the last element. - * @throws NoSuchElementException if this set is empty. - */ - public Object last() - { - synchronized (mutex) - { - return ss.last(); - } - } - - /** - * Returns a subset containing the elements from fromElement to - * the element before toElement. The subset supports all - * operations supported by the underlying set and all actions - * taking place on the subset are also reflected in the underlying - * set. A lock is obtained on the mutex prior to subset creation. - * The subset retains the thread-safe status of this set. - * - * @param fromElement the inclusive lower range of the subset. - * @param toElement the exclusive upper range of the subset. - * @return a subset from fromElement to the element preceding toElement. - * @throws ClassCastException if fromElement or toElement is not comparable - * to the underlying set's contents. - * @throws IllegalArgumentException if fromElement or toElement is outside the set's - * range. - * @throws NullPointerException if fromElement or toElement is null. but the set does - * not allow null elements. - */ - public SortedSet subSet(Object fromElement, Object toElement) - { - synchronized (mutex) - { - return new SynchronizedSortedSet(mutex, - ss.subSet(fromElement, toElement)); - } - } - - /** - * Returns a subset containing all the elements from fromElement onwards. - * The subset supports all operations supported by the underlying - * set and all actions taking place on the subset are also reflected - * in the underlying set. A lock is obtained on the mutex prior to - * subset creation. The subset retains the thread-safe status of - * this set. - * - * @param fromElement the inclusive lower range of the subset. - * @return a subset from fromElement to <code>last()</code>. - * @throws ClassCastException if fromElement is not comparable to the underlying - * set's contents. - * @throws IllegalArgumentException if fromElement is outside the set's range. - * @throws NullPointerException if fromElement is null. but the set does not allow - * null elements. - */ - public SortedSet tailSet(Object fromElement) - { - synchronized (mutex) - { - return new SynchronizedSortedSet(mutex, ss.tailSet(fromElement)); - } - } - } // class SynchronizedSortedSet - - - /** - * Returns an unmodifiable view of the given collection. This allows - * "read-only" access, although changes in the backing collection show up - * in this view. Attempts to modify the collection directly or via iterators - * will fail with {@link UnsupportedOperationException}. Although this view - * prevents changes to the structure of the collection and its elements, the values - * referenced by the objects in the collection can still be modified. - * <p> - * - * Since the collection might be a List or a Set, and those have incompatible - * equals and hashCode requirements, this relies on Object's implementation - * rather than passing those calls on to the wrapped collection. The returned - * Collection implements Serializable, but can only be serialized if - * the collection it wraps is likewise Serializable. - * - * @param c the collection to wrap - * @return a read-only view of the collection - * @see Serializable - */ - public static Collection unmodifiableCollection(Collection c) - { - return new UnmodifiableCollection(c); - } - - /** - * The implementation of {@link #unmodifiableCollection(Collection)}. This - * class name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class UnmodifiableCollection - implements Collection, Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 1820017752578914078L; - - /** - * The wrapped collection. Package visible for use by subclasses. - * @serial the real collection - */ - final Collection c; - - /** - * Wrap a given collection. - * @param c the collection to wrap - * @throws NullPointerException if c is null - */ - UnmodifiableCollection(Collection c) - { - this.c = c; - if (c == null) - throw new NullPointerException(); - } - - /** - * Blocks the addition of elements to the underlying collection. - * This method never returns, throwing an exception instead. - * - * @param o the object to add. - * @return <code>true</code> if the collection was modified as a result of this action. - * @throws UnsupportedOperationException as an unmodifiable collection does not - * support the add operation. - */ - public boolean add(Object o) - { - throw new UnsupportedOperationException(); - } - - /** - * Blocks the addition of a collection of elements to the underlying - * collection. This method never returns, throwing an exception instead. - * - * @param c the collection to add. - * @return <code>true</code> if the collection was modified as a result of this action. - * @throws UnsupportedOperationException as an unmodifiable collection does not - * support the <code>addAll</code> operation. - */ - public boolean addAll(Collection c) - { - throw new UnsupportedOperationException(); - } - - /** - * Blocks the clearing of the underlying collection. This method never - * returns, throwing an exception instead. - * - * @throws UnsupportedOperationException as an unmodifiable collection does - * not support the <code>clear()</code> operation. - */ - public void clear() - { - throw new UnsupportedOperationException(); - } - - /** - * Test whether the underlying collection contains a given object as one of its - * elements. - * - * @param o the element to look for. - * @return <code>true</code> if the underlying collection contains at least - * one element e such that - * <code>o == null ? e == null : o.equals(e)</code>. - * @throws ClassCastException if the type of o is not a valid type for the - * underlying collection. - * @throws NullPointerException if o is null and the underlying collection - * doesn't support null values. - */ - public boolean contains(Object o) - { - return c.contains(o); - } - - /** - * Test whether the underlying collection contains every element in a given - * collection. - * - * @param c the collection to test for. - * @return <code>true</code> if for every element o in c, contains(o) would - * return <code>true</code>. - * @throws ClassCastException if the type of any element in c is not a valid - * type for the underlying collection. - * @throws NullPointerException if some element of c is null and the underlying - * collection does not support null values. - * @throws NullPointerException if c itself is null. - */ - public boolean containsAll(Collection c1) - { - return c.containsAll(c1); - } - - /** - * Tests whether the underlying collection is empty, that is, - * if size() == 0. - * - * @return <code>true</code> if this collection contains no elements. - */ - public boolean isEmpty() - { - return c.isEmpty(); - } - - /** - * Obtain an Iterator over the underlying collection, which maintains - * its unmodifiable nature. - * - * @return an UnmodifiableIterator over the elements of the underlying - * collection, in any order. - */ - public Iterator iterator() - { - return new UnmodifiableIterator(c.iterator()); - } - - /** - * Blocks the removal of an object from the underlying collection. - * This method never returns, throwing an exception instead. - * - * @param o The object to remove. - * @return <code>true</code> if the object was removed (i.e. the underlying - * collection returned 1 or more instances of o). - * @throws UnsupportedOperationException as an unmodifiable collection - * does not support the <code>remove()</code> operation. - */ - public boolean remove(Object o) - { - throw new UnsupportedOperationException(); - } - - /** - * Blocks the removal of a collection of objects from the underlying - * collection. This method never returns, throwing an exception - * instead. - * - * @param c The collection of objects to remove. - * @return <code>true</code> if the collection was modified. - * @throws UnsupportedOperationException as an unmodifiable collection - * does not support the <code>removeAll()</code> operation. - */ - public boolean removeAll(Collection c) - { - throw new UnsupportedOperationException(); - } - - /** - * Blocks the removal of all elements from the underlying collection, - * except those in the supplied collection. This method never returns, - * throwing an exception instead. - * - * @param c The collection of objects to retain. - * @return <code>true</code> if the collection was modified. - * @throws UnsupportedOperationException as an unmodifiable collection - * does not support the <code>retainAll()</code> operation. - */ - public boolean retainAll(Collection c) - { - throw new UnsupportedOperationException(); - } - - /** - * Retrieves the number of elements in the underlying collection. - * - * @return the number of elements in the collection. - */ - public int size() - { - return c.size(); - } - - /** - * Copy the current contents of the underlying collection into an array. - * - * @return an array of type Object[] with a length equal to the size of the - * underlying collection and containing the elements currently in - * the underlying collection, in any order. - */ - public Object[] toArray() - { - return c.toArray(); - } - - /** - * Copy the current contents of the underlying collection into an array. If - * the array passed as an argument has length less than the size of the - * underlying collection, an array of the same run-time type as a, with a length - * equal to the size of the underlying collection, is allocated using reflection. - * Otherwise, a itself is used. The elements of the underlying collection are - * copied into it, and if there is space in the array, the following element is - * set to null. The resultant array is returned. - * Note: The fact that the following element is set to null is only useful - * if it is known that this collection does not contain any null elements. - * - * @param a the array to copy this collection into. - * @return an array containing the elements currently in the underlying - * collection, in any order. - * @throws ArrayStoreException if the type of any element of the - * collection is not a subtype of the element type of a. - */ - public Object[] toArray(Object[] a) - { - return c.toArray(a); - } - - /** - * A textual representation of the unmodifiable collection. - * - * @return The unmodifiable collection in the form of a <code>String</code>. - */ - public String toString() - { - return c.toString(); - } - } // class UnmodifiableCollection - - /** - * The implementation of the various iterator methods in the - * unmodifiable classes. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class UnmodifiableIterator implements Iterator - { - /** - * The wrapped iterator. - */ - private final Iterator i; - - /** - * Only trusted code creates a wrapper. - * @param i the wrapped iterator - */ - UnmodifiableIterator(Iterator i) - { - this.i = i; - } - - /** - * Obtains the next element in the underlying collection. - * - * @return the next element in the collection. - * @throws NoSuchElementException if there are no more elements. - */ - public Object next() - { - return i.next(); - } - /** - * Tests whether there are still elements to be retrieved from the - * underlying collection by <code>next()</code>. When this method - * returns <code>true</code>, an exception will not be thrown on calling - * <code>next()</code>. - * - * @return <code>true</code> if there is at least one more element in the underlying - * collection. - */ - public boolean hasNext() - { - return i.hasNext(); - } - - /** - * Blocks the removal of elements from the underlying collection by the - * iterator. - * - * @throws UnsupportedOperationException as an unmodifiable collection - * does not support the removal of elements by its iterator. - */ - public void remove() - { - throw new UnsupportedOperationException(); - } - } // class UnmodifiableIterator - - /** - * Returns an unmodifiable view of the given list. This allows - * "read-only" access, although changes in the backing list show up - * in this view. Attempts to modify the list directly, via iterators, or - * via sublists, will fail with {@link UnsupportedOperationException}. - * Although this view prevents changes to the structure of the list and - * its elements, the values referenced by the objects in the list can - * still be modified. - * <p> - * - * The returned List implements Serializable, but can only be serialized if - * the list it wraps is likewise Serializable. In addition, if the wrapped - * list implements RandomAccess, this does too. - * - * @param l the list to wrap - * @return a read-only view of the list - * @see Serializable - * @see RandomAccess - */ - public static List unmodifiableList(List l) - { - if (l instanceof RandomAccess) - return new UnmodifiableRandomAccessList(l); - return new UnmodifiableList(l); - } - - /** - * The implementation of {@link #unmodifiableList(List)} for sequential - * lists. This class name is required for compatibility with Sun's JDK - * serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class UnmodifiableList extends UnmodifiableCollection - implements List - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -283967356065247728L; - - - /** - * The wrapped list; stored both here and in the superclass to avoid - * excessive casting. Package visible for use by subclass. - * @serial the wrapped list - */ - final List list; - - /** - * Wrap a given list. - * @param l the list to wrap - * @throws NullPointerException if l is null - */ - UnmodifiableList(List l) - { - super(l); - list = l; - } - - /** - * Blocks the addition of an element to the underlying - * list at a specific index. This method never returns, - * throwing an exception instead. - * - * @param index The index at which to place the new element. - * @param o the object to add. - * @throws UnsupportedOperationException as an unmodifiable - * list doesn't support the <code>add()</code> operation. - */ - public void add(int index, Object o) - { - throw new UnsupportedOperationException(); - } - - /** - * Blocks the addition of a collection of elements to the - * underlying list at a specific index. This method never - * returns, throwing an exception instead. - * - * @param index The index at which to place the new element. - * @param c the collections of objects to add. - * @throws UnsupportedOperationException as an unmodifiable - * list doesn't support the <code>addAll()</code> operation. - */ - public boolean addAll(int index, Collection c) - { - throw new UnsupportedOperationException(); - } - - /** - * Returns <code>true</code> if the object, o, is an instance of - * <code>List</code> with the same size and elements - * as the underlying list. - * - * @param o The object to compare. - * @return <code>true</code> if o is equivalent to the underlying list. - */ - public boolean equals(Object o) - { - return list.equals(o); - } - - /** - * Retrieves the element at a given index in the underlying list. - * - * @param index the index of the element to be returned - * @return the element at index index in this list - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - public Object get(int index) - { - return list.get(index); - } - - /** - * Computes the hash code for the underlying list. - * The exact computation is described in the documentation - * of the <code>List</code> interface. - * - * @return The hash code of the underlying list. - * @see List#hashCode() - */ - public int hashCode() - { - return list.hashCode(); - } - - /** - * Obtain the first index at which a given object is to be found in the - * underlying list. - * - * @param o the object to search for - * @return the least integer n such that <code>o == null ? get(n) == null : - * o.equals(get(n))</code>, or -1 if there is no such index. - * @throws ClassCastException if the type of o is not a valid - * type for the underlying list. - * @throws NullPointerException if o is null and the underlying - * list does not support null values. - */ - public int indexOf(Object o) - { - return list.indexOf(o); - } - - /** - * Obtain the last index at which a given object is to be found in the - * underlying list. - * - * @return the greatest integer n such that <code>o == null ? get(n) == null - * : o.equals(get(n))</code>, or -1 if there is no such index. - * @throws ClassCastException if the type of o is not a valid - * type for the underlying list. - * @throws NullPointerException if o is null and the underlying - * list does not support null values. - */ - public int lastIndexOf(Object o) - { - return list.lastIndexOf(o); - } - - /** - * Obtains a list iterator over the underlying list, starting at the beginning - * and maintaining the unmodifiable nature of this list. - * - * @return a <code>UnmodifiableListIterator</code> over the elements of the - * underlying list, in order, starting at the beginning. - */ - public ListIterator listIterator() - { - return new UnmodifiableListIterator(list.listIterator()); - } - - /** - * Obtains a list iterator over the underlying list, starting at the specified - * index and maintaining the unmodifiable nature of this list. An initial call - * to <code>next()</code> will retrieve the element at the specified index, - * and an initial call to <code>previous()</code> will retrieve the element - * at index - 1. - * - * - * @param index the position, between 0 and size() inclusive, to begin the - * iteration from. - * @return a <code>UnmodifiableListIterator</code> over the elements of the - * underlying list, in order, starting at the specified index. - * @throws IndexOutOfBoundsException if index < 0 || index > size() - */ - public ListIterator listIterator(int index) - { - return new UnmodifiableListIterator(list.listIterator(index)); - } - - /** - * Blocks the removal of the element at the specified index. - * This method never returns, throwing an exception instead. - * - * @param index The index of the element to remove. - * @return the removed element. - * @throws UnsupportedOperationException as an unmodifiable - * list does not support the <code>remove()</code> - * operation. - */ - public Object remove(int index) - { - throw new UnsupportedOperationException(); - } - - /** - * Blocks the replacement of the element at the specified index. - * This method never returns, throwing an exception instead. - * - * @param index The index of the element to replace. - * @param o The new object to place at the specified index. - * @return the replaced element. - * @throws UnsupportedOperationException as an unmodifiable - * list does not support the <code>set()</code> - * operation. - */ - public Object set(int index, Object o) - { - throw new UnsupportedOperationException(); - } - - /** - * Obtain a List view of a subsection of the underlying list, from - * fromIndex (inclusive) to toIndex (exclusive). If the two indices - * are equal, the sublist is empty. The returned list will be - * unmodifiable, like this list. Changes to the elements of the - * returned list will be reflected in the underlying list. No structural - * modifications can take place in either list. - * - * @param fromIndex the index that the returned list should start from - * (inclusive). - * @param toIndex the index that the returned list should go to (exclusive). - * @return a List backed by a subsection of the underlying list. - * @throws IndexOutOfBoundsException if fromIndex < 0 - * || toIndex > size() || fromIndex > toIndex. - */ - public List subList(int fromIndex, int toIndex) - { - return unmodifiableList(list.subList(fromIndex, toIndex)); - } - } // class UnmodifiableList - - /** - * The implementation of {@link #unmodifiableList(List)} for random-access - * lists. This class name is required for compatibility with Sun's JDK - * serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class UnmodifiableRandomAccessList - extends UnmodifiableList implements RandomAccess - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -2542308836966382001L; - - /** - * Wrap a given list. - * @param l the list to wrap - * @throws NullPointerException if l is null - */ - UnmodifiableRandomAccessList(List l) - { - super(l); - } - } // class UnmodifiableRandomAccessList - - /** - * The implementation of {@link UnmodifiableList#listIterator()}. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class UnmodifiableListIterator - extends UnmodifiableIterator implements ListIterator - { - /** - * The wrapped iterator, stored both here and in the superclass to - * avoid excessive casting. - */ - private final ListIterator li; - - /** - * Only trusted code creates a wrapper. - * @param li the wrapped iterator - */ - UnmodifiableListIterator(ListIterator li) - { - super(li); - this.li = li; - } - - /** - * Blocks the addition of an object to the list underlying this iterator. - * This method never returns, throwing an exception instead. - * - * @param o The object to add. - * @throws UnsupportedOperationException as the iterator of an unmodifiable - * list does not support the <code>add()</code> operation. - */ - public void add(Object o) - { - throw new UnsupportedOperationException(); - } - - /** - * Tests whether there are still elements to be retrieved from the - * underlying collection by <code>previous()</code>. When this method - * returns <code>true</code>, an exception will not be thrown on calling - * <code>previous()</code>. - * - * @return <code>true</code> if there is at least one more element prior to the - * current position in the underlying list. - */ - public boolean hasPrevious() - { - return li.hasPrevious(); - } - - /** - * Find the index of the element that would be returned by a call to next. - * If <code>hasNext()</code> returns <code>false</code>, this returns the list size. - * - * @return the index of the element that would be returned by - * <code>next()</code>. - */ - public int nextIndex() - { - return li.nextIndex(); - } - - /** - * Obtains the previous element in the underlying list. - * - * @return the previous element in the list. - * @throws NoSuchElementException if there are no more prior elements. - */ - public Object previous() - { - return li.previous(); - } - - /** - * Find the index of the element that would be returned by a call to - * previous. If <code>hasPrevious()</code> returns <code>false</code>, - * this returns -1. - * - * @return the index of the element that would be returned by - * <code>previous()</code>. - */ - public int previousIndex() - { - return li.previousIndex(); - } - - /** - * Blocks the replacement of an element in the list underlying this - * iterator. This method never returns, throwing an exception instead. - * - * @param o The new object to replace the existing one. - * @throws UnsupportedOperationException as the iterator of an unmodifiable - * list does not support the <code>set()</code> operation. - */ - public void set(Object o) - { - throw new UnsupportedOperationException(); - } - } // class UnmodifiableListIterator - - /** - * Returns an unmodifiable view of the given map. This allows "read-only" - * access, although changes in the backing map show up in this view. - * Attempts to modify the map directly, or via collection views or their - * iterators will fail with {@link UnsupportedOperationException}. - * Although this view prevents changes to the structure of the map and its - * entries, the values referenced by the objects in the map can still be - * modified. - * <p> - * - * The returned Map implements Serializable, but can only be serialized if - * the map it wraps is likewise Serializable. - * - * @param m the map to wrap - * @return a read-only view of the map - * @see Serializable - */ - public static Map unmodifiableMap(Map m) - { - return new UnmodifiableMap(m); - } - - /** - * The implementation of {@link #unmodifiableMap(Map)}. This - * class name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class UnmodifiableMap implements Map, Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -1034234728574286014L; - - /** - * The wrapped map. - * @serial the real map - */ - private final Map m; - - /** - * Cache the entry set. - */ - private transient Set entries; - - /** - * Cache the key set. - */ - private transient Set keys; - - /** - * Cache the value collection. - */ - private transient Collection values; - - /** - * Wrap a given map. - * @param m the map to wrap - * @throws NullPointerException if m is null - */ - UnmodifiableMap(Map m) - { - this.m = m; - if (m == null) - throw new NullPointerException(); - } - - /** - * Blocks the clearing of entries from the underlying map. - * This method never returns, throwing an exception instead. - * - * @throws UnsupportedOperationException as an unmodifiable - * map does not support the <code>clear()</code> operation. - */ - public void clear() - { - throw new UnsupportedOperationException(); - } - - /** - * Returns <code>true</code> if the underlying map contains a mapping for - * the given key. - * - * @param key the key to search for - * @return <code>true</code> if the map contains the key - * @throws ClassCastException if the key is of an inappropriate type - * @throws NullPointerException if key is <code>null</code> but the map - * does not permit null keys - */ - public boolean containsKey(Object key) - { - return m.containsKey(key); - } - - /** - * Returns <code>true</code> if the underlying map contains at least one mapping with - * the given value. In other words, it returns <code>true</code> if a value v exists where - * <code>(value == null ? v == null : value.equals(v))</code>. This usually - * requires linear time. - * - * @param value the value to search for - * @return <code>true</code> if the map contains the value - * @throws ClassCastException if the type of the value is not a valid type - * for this map. - * @throws NullPointerException if the value is null and the map doesn't - * support null values. - */ - public boolean containsValue(Object value) - { - return m.containsValue(value); - } - - /** - * Returns a unmodifiable set view of the entries in the underlying map. - * Each element in the set is a unmodifiable variant of <code>Map.Entry</code>. - * The set is backed by the map, so that changes in one show up in the other. - * Modifications made while an iterator is in progress cause undefined - * behavior. These modifications are again limited to the values of - * the objects. - * - * @return the unmodifiable set view of all mapping entries. - * @see Map.Entry - */ - public Set entrySet() - { - if (entries == null) - entries = new UnmodifiableEntrySet(m.entrySet()); - return entries; - } - - /** - * The implementation of {@link UnmodifiableMap#entrySet()}. This class - * name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class UnmodifiableEntrySet extends UnmodifiableSet - implements Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 7854390611657943733L; - - /** - * Wrap a given set. - * @param s the set to wrap - */ - UnmodifiableEntrySet(Set s) - { - super(s); - } - - // The iterator must return unmodifiable map entries. - public Iterator iterator() - { - return new UnmodifiableIterator(c.iterator()) - { - /** - * Obtains the next element from the underlying set of - * map entries. - * - * @return the next element in the collection. - * @throws NoSuchElementException if there are no more elements. - */ - public Object next() - { - final Map.Entry e = (Map.Entry) super.next(); - return new Map.Entry() - { - /** - * Returns <code>true</code> if the object, o, is also a map entry with an - * identical key and value. - * - * @param o the object to compare. - * @return <code>true</code> if o is an equivalent map entry. - */ - public boolean equals(Object o) - { - return e.equals(o); - } - - /** - * Returns the key of this map entry. - * - * @return the key. - */ - public Object getKey() - { - return e.getKey(); - } - - /** - * Returns the value of this map entry. - * - * @return the value. - */ - public Object getValue() - { - return e.getValue(); - } - - /** - * Computes the hash code of this map entry. - * The computation is described in the <code>Map</code> - * interface documentation. - * - * @return the hash code of this entry. - * @see Map#hashCode() - */ - public int hashCode() - { - return e.hashCode(); - } - - /** - * Blocks the alteration of the value of this map entry. - * This method never returns, throwing an exception instead. - * - * @param value The new value. - * @throws UnsupportedOperationException as an unmodifiable - * map entry does not support the <code>setValue()</code> - * operation. - */ - public Object setValue(Object value) - { - throw new UnsupportedOperationException(); - } - - /** - * Returns a textual representation of the map entry. - * - * @return The map entry as a <code>String</code>. - */ - public String toString() - { - return e.toString(); - } - }; - } - }; - } - } // class UnmodifiableEntrySet - - /** - * Returns <code>true</code> if the object, o, is also an instance - * of <code>Map</code> with an equal set of map entries. - * - * @param o The object to compare. - * @return <code>true</code> if o is an equivalent map. - */ - public boolean equals(Object o) - { - return m.equals(o); - } - - /** - * Returns the value associated with the supplied key or - * null if no such mapping exists. An ambiguity can occur - * if null values are accepted by the underlying map. - * In this case, <code>containsKey()</code> can be used - * to separate the two possible cases of a null result. - * - * @param key The key to look up. - * @return the value associated with the key, or null if key not in map. - * @throws ClassCastException if the key is an inappropriate type. - * @throws NullPointerException if this map does not accept null keys. - * @see #containsKey(Object) - */ - public Object get(Object key) - { - return m.get(key); - } - - /** - * Blocks the addition of a new entry to the underlying map. - * This method never returns, throwing an exception instead. - * - * @param key The new key. - * @param value The new value. - * @return the previous value of the key, or null if there was no mapping. - * @throws UnsupportedOperationException as an unmodifiable - * map does not support the <code>put()</code> operation. - */ - public Object put(Object key, Object value) - { - throw new UnsupportedOperationException(); - } - - /** - * Computes the hash code for the underlying map, as the sum - * of the hash codes of all entries. - * - * @return The hash code of the underlying map. - * @see Map.Entry#hashCode() - */ - public int hashCode() - { - return m.hashCode(); - } - - /** - * Returns <code>true</code> if the underlying map contains no entries. - * - * @return <code>true</code> if the map is empty. - */ - public boolean isEmpty() - { - return m.isEmpty(); - } - - /** - * Returns a unmodifiable set view of the keys in the underlying map. - * The set is backed by the map, so that changes in one show up in the other. - * Modifications made while an iterator is in progress cause undefined - * behavior. These modifications are again limited to the values of - * the keys. - * - * @return the set view of all keys. - */ - public Set keySet() - { - if (keys == null) - keys = new UnmodifiableSet(m.keySet()); - return keys; - } - - /** - * Blocks the addition of the entries in the supplied map. - * This method never returns, throwing an exception instead. - * - * @param m The map, the entries of which should be added - * to the underlying map. - * @throws UnsupportedOperationException as an unmodifiable - * map does not support the <code>putAll</code> operation. - */ - public void putAll(Map m) - { - throw new UnsupportedOperationException(); - } - - /** - * Blocks the removal of an entry from the map. - * This method never returns, throwing an exception instead. - * - * @param o The key of the entry to remove. - * @return The value the key was associated with, or null - * if no such mapping existed. Null is also returned - * if the removed entry had a null key. - * @throws UnsupportedOperationException as an unmodifiable - * map does not support the <code>remove</code> operation. - */ - public Object remove(Object o) - { - throw new UnsupportedOperationException(); - } - - - /** - * Returns the number of key-value mappings in the underlying map. - * If there are more than Integer.MAX_VALUE mappings, Integer.MAX_VALUE - * is returned. - * - * @return the number of mappings. - */ - public int size() - { - return m.size(); - } - - /** - * Returns a textual representation of the map. - * - * @return The map in the form of a <code>String</code>. - */ - public String toString() - { - return m.toString(); - } - - /** - * Returns a unmodifiable collection view of the values in the underlying map. - * The collection is backed by the map, so that changes in one show up in the other. - * Modifications made while an iterator is in progress cause undefined - * behavior. These modifications are again limited to the values of - * the keys. - * - * @return the collection view of all values. - */ - public Collection values() - { - if (values == null) - values = new UnmodifiableCollection(m.values()); - return values; - } - } // class UnmodifiableMap - - /** - * Returns an unmodifiable view of the given set. This allows - * "read-only" access, although changes in the backing set show up - * in this view. Attempts to modify the set directly or via iterators - * will fail with {@link UnsupportedOperationException}. - * Although this view prevents changes to the structure of the set and its - * entries, the values referenced by the objects in the set can still be - * modified. - * <p> - * - * The returned Set implements Serializable, but can only be serialized if - * the set it wraps is likewise Serializable. - * - * @param s the set to wrap - * @return a read-only view of the set - * @see Serializable - */ - public static Set unmodifiableSet(Set s) - { - return new UnmodifiableSet(s); - } - - /** - * The implementation of {@link #unmodifiableSet(Set)}. This class - * name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class UnmodifiableSet extends UnmodifiableCollection - implements Set - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -9215047833775013803L; - - /** - * Wrap a given set. - * @param s the set to wrap - * @throws NullPointerException if s is null - */ - UnmodifiableSet(Set s) - { - super(s); - } - - /** - * Returns <code>true</code> if the object, o, is also an instance of - * <code>Set</code> of the same size and with the same entries. - * - * @return <code>true</code> if o is an equivalent set. - */ - public boolean equals(Object o) - { - return c.equals(o); - } - - /** - * Computes the hash code of this set, as the sum of the - * hash codes of all elements within the set. - * - * @return the hash code of the set. - */ - public int hashCode() - { - return c.hashCode(); - } - } // class UnmodifiableSet - - /** - * Returns an unmodifiable view of the given sorted map. This allows - * "read-only" access, although changes in the backing map show up in this - * view. Attempts to modify the map directly, via subviews, via collection - * views, or iterators, will fail with {@link UnsupportedOperationException}. - * Although this view prevents changes to the structure of the map and its - * entries, the values referenced by the objects in the map can still be - * modified. - * <p> - * - * The returned SortedMap implements Serializable, but can only be - * serialized if the map it wraps is likewise Serializable. - * - * @param m the map to wrap - * @return a read-only view of the map - * @see Serializable - */ - public static SortedMap unmodifiableSortedMap(SortedMap m) - { - return new UnmodifiableSortedMap(m); - } - - /** - * The implementation of {@link #unmodifiableSortedMap(SortedMap)}. This - * class name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class UnmodifiableSortedMap extends UnmodifiableMap - implements SortedMap - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -8806743815996713206L; - - /** - * The wrapped map; stored both here and in the superclass to avoid - * excessive casting. - * @serial the wrapped map - */ - private final SortedMap sm; - - /** - * Wrap a given map. - * @param sm the map to wrap - * @throws NullPointerException if sm is null - */ - UnmodifiableSortedMap(SortedMap sm) - { - super(sm); - this.sm = sm; - } - - /** - * Returns the comparator used in sorting the underlying map, - * or null if it is the keys' natural ordering. - * - * @return the sorting comparator. - */ - public Comparator comparator() - { - return sm.comparator(); - } - - /** - * Returns the first (lowest sorted) key in the map. - * - * @return the first key. - * @throws NoSuchElementException if this map is empty. - */ - public Object firstKey() - { - return sm.firstKey(); - } - - /** - * Returns a unmodifiable view of the portion of the map strictly less - * than toKey. The view is backed by the underlying map, so changes in - * one show up in the other. The submap supports all optional operations - * of the original. This operation is equivalent to - * <code>subMap(firstKey(), toKey)</code>. - * <p> - * - * The returned map throws an IllegalArgumentException any time a key is - * used which is out of the range of toKey. Note that the endpoint, toKey, - * is not included; if you want this value to be included, pass its successor - * object in to toKey. For example, for Integers, you could request - * <code>headMap(new Integer(limit.intValue() + 1))</code>. - * - * @param toKey the exclusive upper range of the submap. - * @return the submap. - * @throws ClassCastException if toKey is not comparable to the map contents. - * @throws IllegalArgumentException if this is a subMap, and toKey is out - * of range. - * @throws NullPointerException if toKey is null but the map does not allow - * null keys. - */ - public SortedMap headMap(Object toKey) - { - return new UnmodifiableSortedMap(sm.headMap(toKey)); - } - - /** - * Returns the last (highest sorted) key in the map. - * - * @return the last key. - * @throws NoSuchElementException if this map is empty. - */ - public Object lastKey() - { - return sm.lastKey(); - } - - /** - * Returns a unmodifiable view of the portion of the map greater than or - * equal to fromKey, and strictly less than toKey. The view is backed by - * the underlying map, so changes in one show up in the other. The submap - * supports all optional operations of the original. - * <p> - * - * The returned map throws an IllegalArgumentException any time a key is - * used which is out of the range of fromKey and toKey. Note that the - * lower endpoint is included, but the upper is not; if you want to - * change the inclusion or exclusion of an endpoint, pass its successor - * object in instead. For example, for Integers, you could request - * <code>subMap(new Integer(lowlimit.intValue() + 1), - * new Integer(highlimit.intValue() + 1))</code> to reverse - * the inclusiveness of both endpoints. - * - * @param fromKey the inclusive lower range of the submap. - * @param toKey the exclusive upper range of the submap. - * @return the submap. - * @throws ClassCastException if fromKey or toKey is not comparable to - * the map contents. - * @throws IllegalArgumentException if this is a subMap, and fromKey or - * toKey is out of range. - * @throws NullPointerException if fromKey or toKey is null but the map - * does not allow null keys. - */ - public SortedMap subMap(Object fromKey, Object toKey) - { - return new UnmodifiableSortedMap(sm.subMap(fromKey, toKey)); - } - - /** - * Returns a unmodifiable view of the portion of the map greater than or - * equal to fromKey. The view is backed by the underlying map, so changes - * in one show up in the other. The submap supports all optional operations - * of the original. - * <p> - * - * The returned map throws an IllegalArgumentException any time a key is - * used which is out of the range of fromKey. Note that the endpoint, fromKey, is - * included; if you do not want this value to be included, pass its successor object in - * to fromKey. For example, for Integers, you could request - * <code>tailMap(new Integer(limit.intValue() + 1))</code>. - * - * @param fromKey the inclusive lower range of the submap - * @return the submap - * @throws ClassCastException if fromKey is not comparable to the map - * contents - * @throws IllegalArgumentException if this is a subMap, and fromKey is out - * of range - * @throws NullPointerException if fromKey is null but the map does not allow - * null keys - */ - public SortedMap tailMap(Object fromKey) - { - return new UnmodifiableSortedMap(sm.tailMap(fromKey)); - } - } // class UnmodifiableSortedMap - - /** - * Returns an unmodifiable view of the given sorted set. This allows - * "read-only" access, although changes in the backing set show up - * in this view. Attempts to modify the set directly, via subsets, or via - * iterators, will fail with {@link UnsupportedOperationException}. - * Although this view prevents changes to the structure of the set and its - * entries, the values referenced by the objects in the set can still be - * modified. - * <p> - * - * The returns SortedSet implements Serializable, but can only be - * serialized if the set it wraps is likewise Serializable. - * - * @param s the set to wrap - * @return a read-only view of the set - * @see Serializable - */ - public static SortedSet unmodifiableSortedSet(SortedSet s) - { - return new UnmodifiableSortedSet(s); - } - - /** - * The implementation of {@link #synchronizedSortedMap(SortedMap)}. This - * class name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class UnmodifiableSortedSet extends UnmodifiableSet - implements SortedSet - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -4929149591599911165L; - - /** - * The wrapped set; stored both here and in the superclass to avoid - * excessive casting. - * @serial the wrapped set - */ - private SortedSet ss; - - /** - * Wrap a given set. - * @param ss the set to wrap - * @throws NullPointerException if ss is null - */ - UnmodifiableSortedSet(SortedSet ss) - { - super(ss); - this.ss = ss; - } - - /** - * Returns the comparator used in sorting the underlying set, - * or null if it is the elements' natural ordering. - * - * @return the sorting comparator - */ - public Comparator comparator() - { - return ss.comparator(); - } - - /** - * Returns the first (lowest sorted) element in the underlying - * set. - * - * @return the first element. - * @throws NoSuchElementException if the set is empty. - */ - public Object first() - { - return ss.first(); - } - - /** - * Returns a unmodifiable view of the portion of the set strictly - * less than toElement. The view is backed by the underlying set, - * so changes in one show up in the other. The subset supports - * all optional operations of the original. This operation - * is equivalent to <code>subSet(first(), toElement)</code>. - * <p> - * - * The returned set throws an IllegalArgumentException any time an element is - * used which is out of the range of toElement. Note that the endpoint, toElement, - * is not included; if you want this value included, pass its successor object in to - * toElement. For example, for Integers, you could request - * <code>headSet(new Integer(limit.intValue() + 1))</code>. - * - * @param toElement the exclusive upper range of the subset - * @return the subset. - * @throws ClassCastException if toElement is not comparable to the set - * contents. - * @throws IllegalArgumentException if this is a subSet, and toElement is out - * of range. - * @throws NullPointerException if toElement is null but the set does not - * allow null elements. - */ - public SortedSet headSet(Object toElement) - { - return new UnmodifiableSortedSet(ss.headSet(toElement)); - } - - /** - * Returns the last (highest sorted) element in the underlying - * set. - * - * @return the last element. - * @throws NoSuchElementException if the set is empty. - */ - public Object last() - { - return ss.last(); - } - - /** - * Returns a unmodifiable view of the portion of the set greater than or - * equal to fromElement, and strictly less than toElement. The view is backed by - * the underlying set, so changes in one show up in the other. The subset - * supports all optional operations of the original. - * <p> - * - * The returned set throws an IllegalArgumentException any time an element is - * used which is out of the range of fromElement and toElement. Note that the - * lower endpoint is included, but the upper is not; if you want to - * change the inclusion or exclusion of an endpoint, pass its successor - * object in instead. For example, for Integers, you can request - * <code>subSet(new Integer(lowlimit.intValue() + 1), - * new Integer(highlimit.intValue() + 1))</code> to reverse - * the inclusiveness of both endpoints. - * - * @param fromElement the inclusive lower range of the subset. - * @param toElement the exclusive upper range of the subset. - * @return the subset. - * @throws ClassCastException if fromElement or toElement is not comparable - * to the set contents. - * @throws IllegalArgumentException if this is a subSet, and fromElement or - * toElement is out of range. - * @throws NullPointerException if fromElement or toElement is null but the - * set does not allow null elements. - */ - public SortedSet subSet(Object fromElement, Object toElement) - { - return new UnmodifiableSortedSet(ss.subSet(fromElement, toElement)); - } - - /** - * Returns a unmodifiable view of the portion of the set greater than or equal to - * fromElement. The view is backed by the underlying set, so changes in one show up - * in the other. The subset supports all optional operations of the original. - * <p> - * - * The returned set throws an IllegalArgumentException any time an element is - * used which is out of the range of fromElement. Note that the endpoint, - * fromElement, is included; if you do not want this value to be included, pass its - * successor object in to fromElement. For example, for Integers, you could request - * <code>tailSet(new Integer(limit.intValue() + 1))</code>. - * - * @param fromElement the inclusive lower range of the subset - * @return the subset. - * @throws ClassCastException if fromElement is not comparable to the set - * contents. - * @throws IllegalArgumentException if this is a subSet, and fromElement is - * out of range. - * @throws NullPointerException if fromElement is null but the set does not - * allow null elements. - */ - public SortedSet tailSet(Object fromElement) - { - return new UnmodifiableSortedSet(ss.tailSet(fromElement)); - } - } // class UnmodifiableSortedSet -} // class Collections |