libjava/ChangeLog:
[official-gcc.git] / libjava / classpath / java / util / Collections.java
blob066c9d5389390618a48803e3179f58b3a4776100
1 /* Collections.java -- Utility class with methods to operate on collections
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006
3 Free Software Foundation, Inc.
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA.
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
25 combination.
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
40 package java.util;
42 import gnu.java.lang.CPStringBuilder;
44 import java.io.Serializable;
46 /**
47 * Utility class consisting of static methods that operate on, or return
48 * Collections. Contains methods to sort, search, reverse, fill and shuffle
49 * Collections, methods to facilitate interoperability with legacy APIs that
50 * are unaware of collections, a method to return a list which consists of
51 * multiple copies of one element, and methods which "wrap" collections to give
52 * them extra properties, such as thread-safety and unmodifiability.
53 * <p>
55 * All methods which take a collection throw a {@link NullPointerException} if
56 * that collection is null. Algorithms which can change a collection may, but
57 * are not required, to throw the {@link UnsupportedOperationException} that
58 * the underlying collection would throw during an attempt at modification.
59 * For example,
60 * <code>Collections.singleton("").addAll(Collections.EMPTY_SET)</code>
61 * does not throw a exception, even though addAll is an unsupported operation
62 * on a singleton; the reason for this is that addAll did not attempt to
63 * modify the set.
65 * @author Original author unknown
66 * @author Eric Blake (ebb9@email.byu.edu)
67 * @author Tom Tromey (tromey@redhat.com)
68 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
69 * @see Collection
70 * @see Set
71 * @see List
72 * @see Map
73 * @see Arrays
74 * @since 1.2
75 * @status updated to 1.5
77 public class Collections
79 /**
80 * Constant used to decide cutoff for when a non-RandomAccess list should
81 * be treated as sequential-access. Basically, quadratic behavior is
82 * acceptable for small lists when the overhead is so small in the first
83 * place. I arbitrarily set it to 16, so it may need some tuning.
85 private static final int LARGE_LIST_SIZE = 16;
87 /**
88 * Determines if a list should be treated as a sequential-access one.
89 * Rather than the old method of JDK 1.3 of assuming only instanceof
90 * AbstractSequentialList should be sequential, this uses the new method
91 * of JDK 1.4 of assuming anything that does NOT implement RandomAccess
92 * and exceeds a large (unspecified) size should be sequential.
94 * @param l the list to check
95 * @return <code>true</code> if it should be treated as sequential-access
97 private static boolean isSequential(List<?> l)
99 return ! (l instanceof RandomAccess) && l.size() > LARGE_LIST_SIZE;
103 * This class is non-instantiable.
105 private Collections()
110 * An immutable, serializable, empty Set.
111 * @see Serializable
113 public static final Set EMPTY_SET = new EmptySet();
116 * Returns an immutable, serializable parameterized empty set.
117 * Unlike the constant <code>EMPTY_SET</code>, the set returned by
118 * this method is type-safe.
120 * @return an empty parameterized set.
121 * @since 1.5
123 public static final <T> Set<T> emptySet()
125 /* FIXME: Could this be optimized? */
126 return new EmptySet<T>();
130 * The implementation of {@link #EMPTY_SET}. This class name is required
131 * for compatibility with Sun's JDK serializability.
133 * @author Eric Blake (ebb9@email.byu.edu)
135 private static final class EmptySet<T> extends AbstractSet<T>
136 implements Serializable
139 * Compatible with JDK 1.4.
141 private static final long serialVersionUID = 1582296315990362920L;
144 * A private constructor adds overhead.
146 EmptySet()
151 * The size: always 0!
152 * @return 0.
154 public int size()
156 return 0;
160 * Returns an iterator that does not iterate.
161 * @return A non-iterating iterator.
163 // This is really cheating! I think it's perfectly valid, though.
164 public Iterator<T> iterator()
166 return (Iterator<T>) EMPTY_LIST.iterator();
169 // The remaining methods are optional, but provide a performance
170 // advantage by not allocating unnecessary iterators in AbstractSet.
172 * The empty set never contains anything.
173 * @param o The object to search for.
174 * @return <code>false</code>.
176 public boolean contains(Object o)
178 return false;
182 * This is true only if the given collection is also empty.
183 * @param c The collection of objects which are to be compared
184 * against the members of this set.
185 * @return <code>true</code> if c is empty.
187 public boolean containsAll(Collection<?> c)
189 return c.isEmpty();
193 * Equal only if the other set is empty.
194 * @param o The object to compare with this set.
195 * @return <code>true</code> if o is an empty instance of <code>Set</code>.
197 public boolean equals(Object o)
199 return o instanceof Set && ((Set) o).isEmpty();
203 * The hashcode is always 0.
204 * @return 0.
206 public int hashCode()
208 return 0;
212 * Always succeeds with a <code>false</code> result.
213 * @param o The object to remove.
214 * @return <code>false</code>.
216 public boolean remove(Object o)
218 return false;
222 * Always succeeds with a <code>false</code> result.
223 * @param c The collection of objects which should
224 * all be removed from this set.
225 * @return <code>false</code>.
227 public boolean removeAll(Collection<?> c)
229 return false;
233 * Always succeeds with a <code>false</code> result.
234 * @param c The collection of objects which should
235 * all be retained within this set.
236 * @return <code>false</code>.
238 public boolean retainAll(Collection<?> c)
240 return false;
244 * The array is always empty.
245 * @return A new array with a size of 0.
247 public Object[] toArray()
249 return new Object[0];
253 * We don't even need to use reflection!
254 * @param a An existing array, which can be empty.
255 * @return The original array with any existing
256 * initial element set to null.
258 public <E> E[] toArray(E[] a)
260 if (a.length > 0)
261 a[0] = null;
262 return a;
266 * The string never changes.
268 * @return the string "[]".
270 public String toString()
272 return "[]";
274 } // class EmptySet
277 * An immutable, serializable, empty List, which implements RandomAccess.
278 * @see Serializable
279 * @see RandomAccess
281 public static final List EMPTY_LIST = new EmptyList();
284 * Returns an immutable, serializable parameterized empty list.
285 * Unlike the constant <code>EMPTY_LIST</code>, the list returned by
286 * this method is type-safe.
288 * @return an empty parameterized list.
289 * @since 1.5
291 public static final <T> List<T> emptyList()
293 /* FIXME: Could this be optimized? */
294 return new EmptyList<T>();
298 * The implementation of {@link #EMPTY_LIST}. This class name is required
299 * for compatibility with Sun's JDK serializability.
301 * @author Eric Blake (ebb9@email.byu.edu)
303 private static final class EmptyList<T> extends AbstractList<T>
304 implements Serializable, RandomAccess
307 * Compatible with JDK 1.4.
309 private static final long serialVersionUID = 8842843931221139166L;
312 * A private constructor adds overhead.
314 EmptyList()
319 * The size is always 0.
320 * @return 0.
322 public int size()
324 return 0;
328 * No matter the index, it is out of bounds. This
329 * method never returns, throwing an exception instead.
331 * @param index The index of the element to retrieve.
332 * @return the object at the specified index.
333 * @throws IndexOutOfBoundsException as any given index
334 * is outside the bounds of an empty array.
336 public T get(int index)
338 throw new IndexOutOfBoundsException();
341 // The remaining methods are optional, but provide a performance
342 // advantage by not allocating unnecessary iterators in AbstractList.
344 * Never contains anything.
345 * @param o The object to search for.
346 * @return <code>false</code>.
348 public boolean contains(Object o)
350 return false;
354 * This is true only if the given collection is also empty.
355 * @param c The collection of objects, which should be compared
356 * against the members of this list.
357 * @return <code>true</code> if c is also empty.
359 public boolean containsAll(Collection<?> c)
361 return c.isEmpty();
365 * Equal only if the other list is empty.
366 * @param o The object to compare against this list.
367 * @return <code>true</code> if o is also an empty instance of
368 * <code>List</code>.
370 public boolean equals(Object o)
372 return o instanceof List && ((List) o).isEmpty();
376 * The hashcode is always 1.
377 * @return 1.
379 public int hashCode()
381 return 1;
385 * Returns -1.
386 * @param o The object to search for.
387 * @return -1.
389 public int indexOf(Object o)
391 return -1;
395 * Returns -1.
396 * @param o The object to search for.
397 * @return -1.
399 public int lastIndexOf(Object o)
401 return -1;
405 * Always succeeds with <code>false</code> result.
406 * @param o The object to remove.
407 * @return -1.
409 public boolean remove(Object o)
411 return false;
415 * Always succeeds with <code>false</code> result.
416 * @param c The collection of objects which should
417 * all be removed from this list.
418 * @return <code>false</code>.
420 public boolean removeAll(Collection<?> c)
422 return false;
426 * Always succeeds with <code>false</code> result.
427 * @param c The collection of objects which should
428 * all be retained within this list.
429 * @return <code>false</code>.
431 public boolean retainAll(Collection<?> c)
433 return false;
437 * The array is always empty.
438 * @return A new array with a size of 0.
440 public Object[] toArray()
442 return new Object[0];
446 * We don't even need to use reflection!
447 * @param a An existing array, which can be empty.
448 * @return The original array with any existing
449 * initial element set to null.
451 public <E> E[] toArray(E[] a)
453 if (a.length > 0)
454 a[0] = null;
455 return a;
459 * The string never changes.
461 * @return the string "[]".
463 public String toString()
465 return "[]";
467 } // class EmptyList
470 * An immutable, serializable, empty Map.
471 * @see Serializable
473 public static final Map EMPTY_MAP = new EmptyMap();
476 * Returns an immutable, serializable parameterized empty map.
477 * Unlike the constant <code>EMPTY_MAP</code>, the map returned by
478 * this method is type-safe.
480 * @return an empty parameterized map.
481 * @since 1.5
483 public static final <K,V> Map<K,V> emptyMap()
485 /* FIXME: Could this be optimized? */
486 return new EmptyMap<K,V>();
490 * The implementation of {@link #EMPTY_MAP}. This class name is required
491 * for compatibility with Sun's JDK serializability.
493 * @author Eric Blake (ebb9@email.byu.edu)
495 private static final class EmptyMap<K, V> extends AbstractMap<K, V>
496 implements Serializable
499 * Compatible with JDK 1.4.
501 private static final long serialVersionUID = 6428348081105594320L;
504 * A private constructor adds overhead.
506 EmptyMap()
511 * There are no entries.
512 * @return The empty set.
514 public Set<Map.Entry<K, V>> entrySet()
516 return EMPTY_SET;
519 // The remaining methods are optional, but provide a performance
520 // advantage by not allocating unnecessary iterators in AbstractMap.
522 * No entries!
523 * @param key The key to search for.
524 * @return <code>false</code>.
526 public boolean containsKey(Object key)
528 return false;
532 * No entries!
533 * @param value The value to search for.
534 * @return <code>false</code>.
536 public boolean containsValue(Object value)
538 return false;
542 * Equal to all empty maps.
543 * @param o The object o to compare against this map.
544 * @return <code>true</code> if o is also an empty instance of
545 * <code>Map</code>.
547 public boolean equals(Object o)
549 return o instanceof Map && ((Map) o).isEmpty();
553 * No mappings, so this returns null.
554 * @param o The key of the object to retrieve.
555 * @return null.
557 public V get(Object o)
559 return null;
563 * The hashcode is always 0.
564 * @return 0.
566 public int hashCode()
568 return 0;
572 * No entries.
573 * @return The empty set.
575 public Set<K> keySet()
577 return EMPTY_SET;
581 * Remove always succeeds, with null result.
582 * @param o The key of the mapping to remove.
583 * @return null, as there is never a mapping for o.
585 public V remove(Object o)
587 return null;
591 * Size is always 0.
592 * @return 0.
594 public int size()
596 return 0;
600 * No entries. Technically, EMPTY_SET, while more specific than a general
601 * Collection, will work. Besides, that's what the JDK uses!
602 * @return The empty set.
604 public Collection<V> values()
606 return EMPTY_SET;
610 * The string never changes.
612 * @return the string "[]".
614 public String toString()
616 return "[]";
618 } // class EmptyMap
622 * Compare two objects with or without a Comparator. If c is null, uses the
623 * natural ordering. Slightly slower than doing it inline if the JVM isn't
624 * clever, but worth it for removing a duplicate of the search code.
625 * Note: This code is also used in Arrays (for sort as well as search).
627 static final <T> int compare(T o1, T o2, Comparator<? super T> c)
629 return c == null ? ((Comparable) o1).compareTo(o2) : c.compare(o1, o2);
633 * Perform a binary search of a List for a key, using the natural ordering of
634 * the elements. The list must be sorted (as by the sort() method) - if it is
635 * not, the behavior of this method is undefined, and may be an infinite
636 * loop. Further, the key must be comparable with every item in the list. If
637 * the list contains the key more than once, any one of them may be found.
638 * <p>
640 * This algorithm behaves in log(n) time for {@link RandomAccess} lists,
641 * and uses a linear search with O(n) link traversals and log(n) comparisons
642 * with {@link AbstractSequentialList} lists. Note: although the
643 * specification allows for an infinite loop if the list is unsorted, it will
644 * not happen in this (Classpath) implementation.
646 * @param l the list to search (must be sorted)
647 * @param key the value to search for
648 * @return the index at which the key was found, or -n-1 if it was not
649 * found, where n is the index of the first value higher than key or
650 * a.length if there is no such value
651 * @throws ClassCastException if key could not be compared with one of the
652 * elements of l
653 * @throws NullPointerException if a null element has compareTo called
654 * @see #sort(List)
656 public static <T> int binarySearch(List<? extends Comparable<? super T>> l,
657 T key)
659 return binarySearch(l, key, null);
663 * Perform a binary search of a List for a key, using a supplied Comparator.
664 * The list must be sorted (as by the sort() method with the same Comparator)
665 * - if it is not, the behavior of this method is undefined, and may be an
666 * infinite loop. Further, the key must be comparable with every item in the
667 * list. If the list contains the key more than once, any one of them may be
668 * found. If the comparator is null, the elements' natural ordering is used.
669 * <p>
671 * This algorithm behaves in log(n) time for {@link RandomAccess} lists,
672 * and uses a linear search with O(n) link traversals and log(n) comparisons
673 * with {@link AbstractSequentialList} lists. Note: although the
674 * specification allows for an infinite loop if the list is unsorted, it will
675 * not happen in this (Classpath) implementation.
677 * @param l the list to search (must be sorted)
678 * @param key the value to search for
679 * @param c the comparator by which the list is sorted
680 * @return the index at which the key was found, or -n-1 if it was not
681 * found, where n is the index of the first value higher than key or
682 * a.length if there is no such value
683 * @throws ClassCastException if key could not be compared with one of the
684 * elements of l
685 * @throws NullPointerException if a null element is compared with natural
686 * ordering (only possible when c is null)
687 * @see #sort(List, Comparator)
689 public static <T> int binarySearch(List<? extends T> l, T key,
690 Comparator<? super T> c)
692 int pos = 0;
693 int low = 0;
694 int hi = l.size() - 1;
696 // We use a linear search with log(n) comparisons using an iterator
697 // if the list is sequential-access.
698 if (isSequential(l))
700 ListIterator<T> itr = ((List<T>) l).listIterator();
701 int i = 0;
702 T o = itr.next(); // Assumes list is not empty (see isSequential)
703 boolean forward = true;
704 while (low <= hi)
706 pos = (low + hi) >>> 1;
707 if (i < pos)
709 if (!forward)
710 itr.next(); // Changing direction first.
711 for ( ; i != pos; i++, o = itr.next())
713 forward = true;
715 else
717 if (forward)
718 itr.previous(); // Changing direction first.
719 for ( ; i != pos; i--, o = itr.previous())
721 forward = false;
723 final int d = compare(o, key, c);
724 if (d == 0)
725 return pos;
726 else if (d > 0)
727 hi = pos - 1;
728 else
729 // This gets the insertion point right on the last loop
730 low = ++pos;
733 else
735 while (low <= hi)
737 pos = (low + hi) >>> 1;
738 final int d = compare(((List<T>) l).get(pos), key, c);
739 if (d == 0)
740 return pos;
741 else if (d > 0)
742 hi = pos - 1;
743 else
744 // This gets the insertion point right on the last loop
745 low = ++pos;
749 // If we failed to find it, we do the same whichever search we did.
750 return -pos - 1;
754 * Copy one list to another. If the destination list is longer than the
755 * source list, the remaining elements are unaffected. This method runs in
756 * linear time.
758 * @param dest the destination list
759 * @param source the source list
760 * @throws IndexOutOfBoundsException if the destination list is shorter
761 * than the source list (the destination will be unmodified)
762 * @throws UnsupportedOperationException if dest.listIterator() does not
763 * support the set operation
765 public static <T> void copy(List<? super T> dest, List<? extends T> source)
767 int pos = source.size();
768 if (dest.size() < pos)
769 throw new IndexOutOfBoundsException("Source does not fit in dest");
771 Iterator<? extends T> i1 = source.iterator();
772 ListIterator<? super T> i2 = dest.listIterator();
774 while (--pos >= 0)
776 i2.next();
777 i2.set(i1.next());
782 * Returns an Enumeration over a collection. This allows interoperability
783 * with legacy APIs that require an Enumeration as input.
785 * @param c the Collection to iterate over
786 * @return an Enumeration backed by an Iterator over c
788 public static <T> Enumeration<T> enumeration(Collection<T> c)
790 final Iterator<T> i = c.iterator();
791 return new Enumeration<T>()
794 * Returns <code>true</code> if there are more elements to
795 * be enumerated.
797 * @return The result of <code>hasNext()</code>
798 * called on the underlying iterator.
800 public final boolean hasMoreElements()
802 return i.hasNext();
806 * Returns the next element to be enumerated.
808 * @return The result of <code>next()</code>
809 * called on the underlying iterator.
811 public final T nextElement()
813 return i.next();
819 * Replace every element of a list with a given value. This method runs in
820 * linear time.
822 * @param l the list to fill.
823 * @param val the object to vill the list with.
824 * @throws UnsupportedOperationException if l.listIterator() does not
825 * support the set operation.
827 public static <T> void fill(List<? super T> l, T val)
829 ListIterator<? super T> itr = l.listIterator();
830 for (int i = l.size() - 1; i >= 0; --i)
832 itr.next();
833 itr.set(val);
838 * Returns the starting index where the specified sublist first occurs
839 * in a larger list, or -1 if there is no matching position. If
840 * <code>target.size() &gt; source.size()</code>, this returns -1,
841 * otherwise this implementation uses brute force, checking for
842 * <code>source.sublist(i, i + target.size()).equals(target)</code>
843 * for all possible i.
845 * @param source the list to search
846 * @param target the sublist to search for
847 * @return the index where found, or -1
848 * @since 1.4
850 public static int indexOfSubList(List<?> source, List<?> target)
852 int ssize = source.size();
853 for (int i = 0, j = target.size(); j <= ssize; i++, j++)
854 if (source.subList(i, j).equals(target))
855 return i;
856 return -1;
860 * Returns the starting index where the specified sublist last occurs
861 * in a larger list, or -1 if there is no matching position. If
862 * <code>target.size() &gt; source.size()</code>, this returns -1,
863 * otherwise this implementation uses brute force, checking for
864 * <code>source.sublist(i, i + target.size()).equals(target)</code>
865 * for all possible i.
867 * @param source the list to search
868 * @param target the sublist to search for
869 * @return the index where found, or -1
870 * @since 1.4
872 public static int lastIndexOfSubList(List<?> source, List<?> target)
874 int ssize = source.size();
875 for (int i = ssize - target.size(), j = ssize; i >= 0; i--, j--)
876 if (source.subList(i, j).equals(target))
877 return i;
878 return -1;
882 * Returns an ArrayList holding the elements visited by a given
883 * Enumeration. This method exists for interoperability between legacy
884 * APIs and the new Collection API.
886 * @param e the enumeration to put in a list
887 * @return a list containing the enumeration elements
888 * @see ArrayList
889 * @since 1.4
891 public static <T> ArrayList<T> list(Enumeration<T> e)
893 ArrayList<T> l = new ArrayList<T>();
894 while (e.hasMoreElements())
895 l.add(e.nextElement());
896 return l;
900 * Find the maximum element in a Collection, according to the natural
901 * ordering of the elements. This implementation iterates over the
902 * Collection, so it works in linear time.
904 * @param c the Collection to find the maximum element of
905 * @return the maximum element of c
906 * @exception NoSuchElementException if c is empty
907 * @exception ClassCastException if elements in c are not mutually comparable
908 * @exception NullPointerException if null.compareTo is called
910 public static <T extends Object & Comparable<? super T>>
911 T max(Collection<? extends T> c)
913 return max(c, null);
917 * Find the maximum element in a Collection, according to a specified
918 * Comparator. This implementation iterates over the Collection, so it
919 * works in linear time.
921 * @param c the Collection to find the maximum element of
922 * @param order the Comparator to order the elements by, or null for natural
923 * ordering
924 * @return the maximum element of c
925 * @throws NoSuchElementException if c is empty
926 * @throws ClassCastException if elements in c are not mutually comparable
927 * @throws NullPointerException if null is compared by natural ordering
928 * (only possible when order is null)
930 public static <T> T max(Collection<? extends T> c,
931 Comparator<? super T> order)
933 Iterator<? extends T> itr = c.iterator();
934 T max = itr.next(); // throws NoSuchElementException
935 int csize = c.size();
936 for (int i = 1; i < csize; i++)
938 T o = itr.next();
939 if (compare(max, o, order) < 0)
940 max = o;
942 return max;
946 * Find the minimum element in a Collection, according to the natural
947 * ordering of the elements. This implementation iterates over the
948 * Collection, so it works in linear time.
950 * @param c the Collection to find the minimum element of
951 * @return the minimum element of c
952 * @throws NoSuchElementException if c is empty
953 * @throws ClassCastException if elements in c are not mutually comparable
954 * @throws NullPointerException if null.compareTo is called
956 public static <T extends Object & Comparable<? super T>>
957 T min(Collection<? extends T> c)
959 return min(c, null);
963 * Find the minimum element in a Collection, according to a specified
964 * Comparator. This implementation iterates over the Collection, so it
965 * works in linear time.
967 * @param c the Collection to find the minimum element of
968 * @param order the Comparator to order the elements by, or null for natural
969 * ordering
970 * @return the minimum element of c
971 * @throws NoSuchElementException if c is empty
972 * @throws ClassCastException if elements in c are not mutually comparable
973 * @throws NullPointerException if null is compared by natural ordering
974 * (only possible when order is null)
976 public static <T> T min(Collection<? extends T> c,
977 Comparator<? super T> order)
979 Iterator<? extends T> itr = c.iterator();
980 T min = itr.next(); // throws NoSuchElementExcception
981 int csize = c.size();
982 for (int i = 1; i < csize; i++)
984 T o = itr.next();
985 if (compare(min, o, order) > 0)
986 min = o;
988 return min;
992 * Creates an immutable list consisting of the same object repeated n times.
993 * The returned object is tiny, consisting of only a single reference to the
994 * object and a count of the number of elements. It is Serializable, and
995 * implements RandomAccess. You can use it in tandem with List.addAll for
996 * fast list construction.
998 * @param n the number of times to repeat the object
999 * @param o the object to repeat
1000 * @return a List consisting of n copies of o
1001 * @throws IllegalArgumentException if n &lt; 0
1002 * @see List#addAll(Collection)
1003 * @see Serializable
1004 * @see RandomAccess
1006 public static <T> List<T> nCopies(final int n, final T o)
1008 return new CopiesList<T>(n, o);
1012 * The implementation of {@link #nCopies(int, Object)}. This class name
1013 * is required for compatibility with Sun's JDK serializability.
1015 * @author Eric Blake (ebb9@email.byu.edu)
1017 private static final class CopiesList<T> extends AbstractList<T>
1018 implements Serializable, RandomAccess
1021 * Compatible with JDK 1.4.
1023 private static final long serialVersionUID = 2739099268398711800L;
1026 * The count of elements in this list.
1027 * @serial the list size
1029 private final int n;
1032 * The repeated list element.
1033 * @serial the list contents
1035 private final T element;
1038 * Constructs the list.
1040 * @param n the count
1041 * @param o the object
1042 * @throws IllegalArgumentException if n &lt; 0
1044 CopiesList(int n, T o)
1046 if (n < 0)
1047 throw new IllegalArgumentException();
1048 this.n = n;
1049 element = o;
1053 * The size is fixed.
1054 * @return The size of the list.
1056 public int size()
1058 return n;
1062 * The same element is returned.
1063 * @param index The index of the element to be returned (irrelevant
1064 * as the list contains only copies of <code>element</code>).
1065 * @return The element used by this list.
1067 public T get(int index)
1069 if (index < 0 || index >= n)
1070 throw new IndexOutOfBoundsException();
1071 return element;
1074 // The remaining methods are optional, but provide a performance
1075 // advantage by not allocating unnecessary iterators in AbstractList.
1077 * This list only contains one element.
1078 * @param o The object to search for.
1079 * @return <code>true</code> if o is the element used by this list.
1081 public boolean contains(Object o)
1083 return n > 0 && equals(o, element);
1087 * The index is either 0 or -1.
1088 * @param o The object to find the index of.
1089 * @return 0 if <code>o == element</code>, -1 if not.
1091 public int indexOf(Object o)
1093 return (n > 0 && equals(o, element)) ? 0 : -1;
1097 * The index is either n-1 or -1.
1098 * @param o The object to find the last index of.
1099 * @return The last index in the list if <code>o == element</code>,
1100 * -1 if not.
1102 public int lastIndexOf(Object o)
1104 return equals(o, element) ? n - 1 : -1;
1108 * A subList is just another CopiesList.
1109 * @param from The starting bound of the sublist.
1110 * @param to The ending bound of the sublist.
1111 * @return A list of copies containing <code>from - to</code>
1112 * elements, all of which are equal to the element
1113 * used by this list.
1115 public List<T> subList(int from, int to)
1117 if (from < 0 || to > n)
1118 throw new IndexOutOfBoundsException();
1119 return new CopiesList<T>(to - from, element);
1123 * The array is easy.
1124 * @return An array of size n filled with copies of
1125 * the element used by this list.
1127 public Object[] toArray()
1129 Object[] a = new Object[n];
1130 Arrays.fill(a, element);
1131 return a;
1135 * The string is easy to generate.
1136 * @return A string representation of the list.
1138 public String toString()
1140 CPStringBuilder r = new CPStringBuilder("{");
1141 for (int i = n - 1; --i > 0; )
1142 r.append(element).append(", ");
1143 r.append(element).append("}");
1144 return r.toString();
1146 } // class CopiesList
1149 * Replace all instances of one object with another in the specified list.
1150 * The list does not change size. An element e is replaced if
1151 * <code>oldval == null ? e == null : oldval.equals(e)</code>.
1153 * @param list the list to iterate over
1154 * @param oldval the element to replace
1155 * @param newval the new value for the element
1156 * @return <code>true</code> if a replacement occurred.
1157 * @throws UnsupportedOperationException if the list iterator does not allow
1158 * for the set operation
1159 * @throws ClassCastException if newval is of a type which cannot be added
1160 * to the list
1161 * @throws IllegalArgumentException if some other aspect of newval stops
1162 * it being added to the list
1163 * @since 1.4
1165 public static <T> boolean replaceAll(List<T> list, T oldval, T newval)
1167 ListIterator<T> itr = list.listIterator();
1168 boolean replace_occured = false;
1169 for (int i = list.size(); --i >= 0; )
1170 if (AbstractCollection.equals(oldval, itr.next()))
1172 itr.set(newval);
1173 replace_occured = true;
1175 return replace_occured;
1179 * Reverse a given list. This method works in linear time.
1181 * @param l the list to reverse
1182 * @throws UnsupportedOperationException if l.listIterator() does not
1183 * support the set operation
1185 public static void reverse(List<?> l)
1187 ListIterator i1 = l.listIterator();
1188 int pos1 = 1;
1189 int pos2 = l.size();
1190 ListIterator i2 = l.listIterator(pos2);
1191 while (pos1 < pos2)
1193 Object o1 = i1.next();
1194 Object o2 = i2.previous();
1195 i1.set(o2);
1196 i2.set(o1);
1197 ++pos1;
1198 --pos2;
1203 * Get a comparator that implements the reverse of the ordering
1204 * specified by the given Comparator. If the Comparator is null,
1205 * this is equivalent to {@link #reverseOrder()}. The return value
1206 * of this method is Serializable, if the specified Comparator is
1207 * either Serializable or null.
1209 * @param c the comparator to invert
1210 * @return a comparator that imposes reverse ordering
1211 * @see Comparable
1212 * @see Serializable
1214 * @since 1.5
1216 public static <T> Comparator<T> reverseOrder(final Comparator<T> c)
1218 if (c == null)
1219 return (Comparator<T>) rcInstance;
1220 return new ReverseComparator<T> ()
1222 public int compare(T a, T b)
1224 return - c.compare(a, b);
1230 * Get a comparator that implements the reverse of natural ordering. In
1231 * other words, this sorts Comparable objects opposite of how their
1232 * compareTo method would sort. This makes it easy to sort into reverse
1233 * order, by simply passing Collections.reverseOrder() to the sort method.
1234 * The return value of this method is Serializable.
1236 * @return a comparator that imposes reverse natural ordering
1237 * @see Comparable
1238 * @see Serializable
1240 public static <T> Comparator<T> reverseOrder()
1242 return (Comparator<T>) rcInstance;
1246 * The object for {@link #reverseOrder()}.
1248 private static final ReverseComparator rcInstance = new ReverseComparator();
1251 * The implementation of {@link #reverseOrder()}. This class name
1252 * is required for compatibility with Sun's JDK serializability.
1254 * @author Eric Blake (ebb9@email.byu.edu)
1256 private static class ReverseComparator<T>
1257 implements Comparator<T>, Serializable
1260 * Compatible with JDK 1.4.
1262 private static final long serialVersionUID = 7207038068494060240L;
1265 * A private constructor adds overhead.
1267 ReverseComparator()
1272 * Compare two objects in reverse natural order.
1274 * @param a the first object
1275 * @param b the second object
1276 * @return &lt;, ==, or &gt; 0 according to b.compareTo(a)
1278 public int compare(T a, T b)
1280 return ((Comparable) b).compareTo(a);
1285 * Rotate the elements in a list by a specified distance. After calling this
1286 * method, the element now at index <code>i</code> was formerly at index
1287 * <code>(i - distance) mod list.size()</code>. The list size is unchanged.
1288 * <p>
1290 * For example, suppose a list contains <code>[t, a, n, k, s]</code>. After
1291 * either <code>Collections.rotate(l, 4)</code> or
1292 * <code>Collections.rotate(l, -1)</code>, the new contents are
1293 * <code>[s, t, a, n, k]</code>. This can be applied to sublists to rotate
1294 * just a portion of the list. For example, to move element <code>a</code>
1295 * forward two positions in the original example, use
1296 * <code>Collections.rotate(l.subList(1, 3+1), -1)</code>, which will
1297 * result in <code>[t, n, k, a, s]</code>.
1298 * <p>
1300 * If the list is small or implements {@link RandomAccess}, the
1301 * implementation exchanges the first element to its destination, then the
1302 * displaced element, and so on until a circuit has been completed. The
1303 * process is repeated if needed on the second element, and so forth, until
1304 * all elements have been swapped. For large non-random lists, the
1305 * implementation breaks the list into two sublists at index
1306 * <code>-distance mod size</code>, calls {@link #reverse(List)} on the
1307 * pieces, then reverses the overall list.
1309 * @param list the list to rotate
1310 * @param distance the distance to rotate by; unrestricted in value
1311 * @throws UnsupportedOperationException if the list does not support set
1312 * @since 1.4
1314 public static void rotate(List<?> list, int distance)
1316 int size = list.size();
1317 if (size == 0)
1318 return;
1319 distance %= size;
1320 if (distance == 0)
1321 return;
1322 if (distance < 0)
1323 distance += size;
1325 if (isSequential(list))
1327 reverse(list);
1328 reverse(list.subList(0, distance));
1329 reverse(list.subList(distance, size));
1331 else
1333 // Determine the least common multiple of distance and size, as there
1334 // are (distance / LCM) loops to cycle through.
1335 int a = size;
1336 int lcm = distance;
1337 int b = a % lcm;
1338 while (b != 0)
1340 a = lcm;
1341 lcm = b;
1342 b = a % lcm;
1345 // Now, make the swaps. We must take the remainder every time through
1346 // the inner loop so that we don't overflow i to negative values.
1347 List<Object> objList = (List<Object>) list;
1348 while (--lcm >= 0)
1350 Object o = objList.get(lcm);
1351 for (int i = lcm + distance; i != lcm; i = (i + distance) % size)
1352 o = objList.set(i, o);
1353 objList.set(lcm, o);
1359 * Shuffle a list according to a default source of randomness. The algorithm
1360 * used iterates backwards over the list, swapping each element with an
1361 * element randomly selected from the elements in positions less than or
1362 * equal to it (using r.nextInt(int)).
1363 * <p>
1365 * This algorithm would result in a perfectly fair shuffle (that is, each
1366 * element would have an equal chance of ending up in any position) if r were
1367 * a perfect source of randomness. In practice the results are merely very
1368 * close to perfect.
1369 * <p>
1371 * This method operates in linear time. To do this on large lists which do
1372 * not implement {@link RandomAccess}, a temporary array is used to acheive
1373 * this speed, since it would be quadratic access otherwise.
1375 * @param l the list to shuffle
1376 * @throws UnsupportedOperationException if l.listIterator() does not
1377 * support the set operation
1379 public static void shuffle(List<?> l)
1381 if (defaultRandom == null)
1383 synchronized (Collections.class)
1385 if (defaultRandom == null)
1386 defaultRandom = new Random();
1389 shuffle(l, defaultRandom);
1393 * Cache a single Random object for use by shuffle(List). This improves
1394 * performance as well as ensuring that sequential calls to shuffle() will
1395 * not result in the same shuffle order occurring: the resolution of
1396 * System.currentTimeMillis() is not sufficient to guarantee a unique seed.
1398 private static Random defaultRandom = null;
1401 * Shuffle a list according to a given source of randomness. The algorithm
1402 * used iterates backwards over the list, swapping each element with an
1403 * element randomly selected from the elements in positions less than or
1404 * equal to it (using r.nextInt(int)).
1405 * <p>
1407 * This algorithm would result in a perfectly fair shuffle (that is, each
1408 * element would have an equal chance of ending up in any position) if r were
1409 * a perfect source of randomness. In practise (eg if r = new Random()) the
1410 * results are merely very close to perfect.
1411 * <p>
1413 * This method operates in linear time. To do this on large lists which do
1414 * not implement {@link RandomAccess}, a temporary array is used to acheive
1415 * this speed, since it would be quadratic access otherwise.
1417 * @param l the list to shuffle
1418 * @param r the source of randomness to use for the shuffle
1419 * @throws UnsupportedOperationException if l.listIterator() does not
1420 * support the set operation
1422 public static void shuffle(List<?> l, Random r)
1424 int lsize = l.size();
1425 List<Object> list = (List<Object>) l;
1426 ListIterator<Object> i = list.listIterator(lsize);
1427 boolean sequential = isSequential(l);
1428 Object[] a = null; // stores a copy of the list for the sequential case
1430 if (sequential)
1431 a = list.toArray();
1433 for (int pos = lsize - 1; pos > 0; --pos)
1435 // Obtain a random position to swap with. pos + 1 is used so that the
1436 // range of the random number includes the current position.
1437 int swap = r.nextInt(pos + 1);
1439 // Swap the desired element.
1440 Object o;
1441 if (sequential)
1443 o = a[swap];
1444 a[swap] = i.previous();
1446 else
1447 o = list.set(swap, i.previous());
1449 i.set(o);
1454 * Returns the frequency of the specified object within the supplied
1455 * collection. The frequency represents the number of occurrences of
1456 * elements within the collection which return <code>true</code> when
1457 * compared with the object using the <code>equals</code> method.
1459 * @param c the collection to scan for occurrences of the object.
1460 * @param o the object to locate occurrances of within the collection.
1461 * @throws NullPointerException if the collection is <code>null</code>.
1462 * @since 1.5
1464 public static int frequency (Collection<?> c, Object o)
1466 int result = 0;
1467 final Iterator<?> it = c.iterator();
1468 while (it.hasNext())
1470 Object v = it.next();
1471 if (AbstractCollection.equals(o, v))
1472 ++result;
1474 return result;
1478 * Adds all the specified elements to the given collection, in a similar
1479 * way to the <code>addAll</code> method of the <code>Collection</code>.
1480 * However, this is a variable argument method which allows the new elements
1481 * to be specified individually or in array form, as opposed to the list
1482 * required by the collection's <code>addAll</code> method. This has
1483 * benefits in both simplicity (multiple elements can be added without
1484 * having to be wrapped inside a grouping structure) and efficiency
1485 * (as a redundant list doesn't have to be created to add an individual
1486 * set of elements or an array).
1488 * @param c the collection to which the elements should be added.
1489 * @param a the elements to be added to the collection.
1490 * @return true if the collection changed its contents as a result.
1491 * @throws UnsupportedOperationException if the collection does not support
1492 * addition.
1493 * @throws NullPointerException if one or more elements in a are null,
1494 * and the collection does not allow null
1495 * elements. This exception is also thrown
1496 * if either <code>c</code> or <code>a</code>
1497 * are null.
1498 * @throws IllegalArgumentException if the collection won't allow an element
1499 * to be added for some other reason.
1500 * @since 1.5
1502 public static <T> boolean addAll(Collection<? super T> c, T... a)
1504 boolean overall = false;
1506 for (T element : a)
1508 boolean result = c.add(element);
1509 if (result)
1510 overall = true;
1512 return overall;
1516 * Returns true if the two specified collections have no elements in
1517 * common. This method may give unusual results if one or both collections
1518 * use a non-standard equality test. In the trivial case of comparing
1519 * a collection with itself, this method returns true if, and only if,
1520 * the collection is empty.
1522 * @param c1 the first collection to compare.
1523 * @param c2 the second collection to compare.
1524 * @return true if the collections are disjoint.
1525 * @throws NullPointerException if either collection is null.
1526 * @since 1.5
1528 public static boolean disjoint(Collection<?> c1, Collection<?> c2)
1530 Collection<Object> oc1 = (Collection<Object>) c1;
1531 final Iterator<Object> it = oc1.iterator();
1532 while (it.hasNext())
1533 if (c2.contains(it.next()))
1534 return false;
1535 return true;
1540 * Obtain an immutable Set consisting of a single element. The return value
1541 * of this method is Serializable.
1543 * @param o the single element
1544 * @return an immutable Set containing only o
1545 * @see Serializable
1547 public static <T> Set<T> singleton(T o)
1549 return new SingletonSet<T>(o);
1553 * The implementation of {@link #singleton(Object)}. This class name
1554 * is required for compatibility with Sun's JDK serializability.
1556 * @author Eric Blake (ebb9@email.byu.edu)
1558 private static final class SingletonSet<T> extends AbstractSet<T>
1559 implements Serializable
1562 * Compatible with JDK 1.4.
1564 private static final long serialVersionUID = 3193687207550431679L;
1568 * The single element; package visible for use in nested class.
1569 * @serial the singleton
1571 final T element;
1574 * Construct a singleton.
1575 * @param o the element
1577 SingletonSet(T o)
1579 element = o;
1583 * The size: always 1!
1584 * @return 1.
1586 public int size()
1588 return 1;
1592 * Returns an iterator over the lone element.
1594 public Iterator<T> iterator()
1596 return new Iterator<T>()
1599 * Flag to indicate whether or not the element has
1600 * been retrieved.
1602 private boolean hasNext = true;
1605 * Returns <code>true</code> if elements still remain to be
1606 * iterated through.
1608 * @return <code>true</code> if the element has not yet been returned.
1610 public boolean hasNext()
1612 return hasNext;
1616 * Returns the element.
1618 * @return The element used by this singleton.
1619 * @throws NoSuchElementException if the object
1620 * has already been retrieved.
1622 public T next()
1624 if (hasNext)
1626 hasNext = false;
1627 return element;
1629 else
1630 throw new NoSuchElementException();
1634 * Removes the element from the singleton.
1635 * As this set is immutable, this will always
1636 * throw an exception.
1638 * @throws UnsupportedOperationException as the
1639 * singleton set doesn't support
1640 * <code>remove()</code>.
1642 public void remove()
1644 throw new UnsupportedOperationException();
1649 // The remaining methods are optional, but provide a performance
1650 // advantage by not allocating unnecessary iterators in AbstractSet.
1652 * The set only contains one element.
1654 * @param o The object to search for.
1655 * @return <code>true</code> if o == the element of the singleton.
1657 public boolean contains(Object o)
1659 return equals(o, element);
1663 * This is true if the other collection only contains the element.
1665 * @param c A collection to compare against this singleton.
1666 * @return <code>true</code> if c only contains either no elements or
1667 * elements equal to the element in this singleton.
1669 public boolean containsAll(Collection<?> c)
1671 Iterator<?> i = c.iterator();
1672 int pos = c.size();
1673 while (--pos >= 0)
1674 if (! equals(i.next(), element))
1675 return false;
1676 return true;
1680 * The hash is just that of the element.
1682 * @return The hashcode of the element.
1684 public int hashCode()
1686 return hashCode(element);
1690 * Returning an array is simple.
1692 * @return An array containing the element.
1694 public Object[] toArray()
1696 return new Object[] {element};
1700 * Obvious string.
1702 * @return The string surrounded by enclosing
1703 * square brackets.
1705 public String toString()
1707 return "[" + element + "]";
1709 } // class SingletonSet
1712 * Obtain an immutable List consisting of a single element. The return value
1713 * of this method is Serializable, and implements RandomAccess.
1715 * @param o the single element
1716 * @return an immutable List containing only o
1717 * @see Serializable
1718 * @see RandomAccess
1719 * @since 1.3
1721 public static <T> List<T> singletonList(T o)
1723 return new SingletonList<T>(o);
1727 * The implementation of {@link #singletonList(Object)}. This class name
1728 * is required for compatibility with Sun's JDK serializability.
1730 * @author Eric Blake (ebb9@email.byu.edu)
1732 private static final class SingletonList<T> extends AbstractList<T>
1733 implements Serializable, RandomAccess
1736 * Compatible with JDK 1.4.
1738 private static final long serialVersionUID = 3093736618740652951L;
1741 * The single element.
1742 * @serial the singleton
1744 private final T element;
1747 * Construct a singleton.
1748 * @param o the element
1750 SingletonList(T o)
1752 element = o;
1756 * The size: always 1!
1757 * @return 1.
1759 public int size()
1761 return 1;
1765 * Only index 0 is valid.
1766 * @param index The index of the element
1767 * to retrieve.
1768 * @return The singleton's element if the
1769 * index is 0.
1770 * @throws IndexOutOfBoundsException if
1771 * index is not 0.
1773 public T get(int index)
1775 if (index == 0)
1776 return element;
1777 throw new IndexOutOfBoundsException();
1780 // The remaining methods are optional, but provide a performance
1781 // advantage by not allocating unnecessary iterators in AbstractList.
1783 * The set only contains one element.
1785 * @param o The object to search for.
1786 * @return <code>true</code> if o == the singleton element.
1788 public boolean contains(Object o)
1790 return equals(o, element);
1794 * This is true if the other collection only contains the element.
1796 * @param c A collection to compare against this singleton.
1797 * @return <code>true</code> if c only contains either no elements or
1798 * elements equal to the element in this singleton.
1800 public boolean containsAll(Collection<?> c)
1802 Iterator<?> i = c.iterator();
1803 int pos = c.size();
1804 while (--pos >= 0)
1805 if (! equals(i.next(), element))
1806 return false;
1807 return true;
1811 * Speed up the hashcode computation.
1813 * @return The hashcode of the list, based
1814 * on the hashcode of the singleton element.
1816 public int hashCode()
1818 return 31 + hashCode(element);
1822 * Either the list has it or not.
1824 * @param o The object to find the first index of.
1825 * @return 0 if o is the singleton element, -1 if not.
1827 public int indexOf(Object o)
1829 return equals(o, element) ? 0 : -1;
1833 * Either the list has it or not.
1835 * @param o The object to find the last index of.
1836 * @return 0 if o is the singleton element, -1 if not.
1838 public int lastIndexOf(Object o)
1840 return equals(o, element) ? 0 : -1;
1844 * Sublists are limited in scope.
1846 * @param from The starting bound for the sublist.
1847 * @param to The ending bound for the sublist.
1848 * @return Either an empty list if both bounds are
1849 * 0 or 1, or this list if the bounds are 0 and 1.
1850 * @throws IllegalArgumentException if <code>from > to</code>
1851 * @throws IndexOutOfBoundsException if either bound is greater
1852 * than 1.
1854 public List<T> subList(int from, int to)
1856 if (from == to && (to == 0 || to == 1))
1857 return EMPTY_LIST;
1858 if (from == 0 && to == 1)
1859 return this;
1860 if (from > to)
1861 throw new IllegalArgumentException();
1862 throw new IndexOutOfBoundsException();
1866 * Returning an array is simple.
1868 * @return An array containing the element.
1870 public Object[] toArray()
1872 return new Object[] {element};
1876 * Obvious string.
1878 * @return The string surrounded by enclosing
1879 * square brackets.
1881 public String toString()
1883 return "[" + element + "]";
1885 } // class SingletonList
1888 * Obtain an immutable Map consisting of a single key-value pair.
1889 * The return value of this method is Serializable.
1891 * @param key the single key
1892 * @param value the single value
1893 * @return an immutable Map containing only the single key-value pair
1894 * @see Serializable
1895 * @since 1.3
1897 public static <K, V> Map<K, V> singletonMap(K key, V value)
1899 return new SingletonMap<K, V>(key, value);
1903 * The implementation of {@link #singletonMap(Object, Object)}. This class
1904 * name is required for compatibility with Sun's JDK serializability.
1906 * @author Eric Blake (ebb9@email.byu.edu)
1908 private static final class SingletonMap<K, V> extends AbstractMap<K, V>
1909 implements Serializable
1912 * Compatible with JDK 1.4.
1914 private static final long serialVersionUID = -6979724477215052911L;
1917 * The single key.
1918 * @serial the singleton key
1920 private final K k;
1923 * The corresponding value.
1924 * @serial the singleton value
1926 private final V v;
1929 * Cache the entry set.
1931 private transient Set<Map.Entry<K, V>> entries;
1934 * Construct a singleton.
1935 * @param key the key
1936 * @param value the value
1938 SingletonMap(K key, V value)
1940 k = key;
1941 v = value;
1945 * There is a single immutable entry.
1947 * @return A singleton containing the map entry.
1949 public Set<Map.Entry<K, V>> entrySet()
1951 if (entries == null)
1953 Map.Entry<K,V> entry = new AbstractMap.SimpleEntry<K, V>(k, v)
1956 * Sets the value of the map entry to the supplied value.
1957 * An exception is always thrown, as the map is immutable.
1959 * @param o The new value.
1960 * @return The old value.
1961 * @throws UnsupportedOperationException as setting the value
1962 * is not supported.
1964 public V setValue(V o)
1966 throw new UnsupportedOperationException();
1969 entries = singleton(entry);
1971 return entries;
1974 // The remaining methods are optional, but provide a performance
1975 // advantage by not allocating unnecessary iterators in AbstractMap.
1977 * Single entry.
1979 * @param key The key to look for.
1980 * @return <code>true</code> if the key is the same as the one used by
1981 * this map.
1983 public boolean containsKey(Object key)
1985 return equals(key, k);
1989 * Single entry.
1991 * @param value The value to look for.
1992 * @return <code>true</code> if the value is the same as the one used by
1993 * this map.
1995 public boolean containsValue(Object value)
1997 return equals(value, v);
2001 * Single entry.
2003 * @param key The key of the value to be retrieved.
2004 * @return The singleton value if the key is the same as the
2005 * singleton key, null otherwise.
2007 public V get(Object key)
2009 return equals(key, k) ? v : null;
2013 * Calculate the hashcode directly.
2015 * @return The hashcode computed from the singleton key
2016 * and the singleton value.
2018 public int hashCode()
2020 return hashCode(k) ^ hashCode(v);
2024 * Return the keyset.
2026 * @return A singleton containing the key.
2028 public Set<K> keySet()
2030 if (keys == null)
2031 keys = singleton(k);
2032 return keys;
2036 * The size: always 1!
2038 * @return 1.
2040 public int size()
2042 return 1;
2046 * Return the values. Technically, a singleton, while more specific than
2047 * a general Collection, will work. Besides, that's what the JDK uses!
2049 * @return A singleton containing the value.
2051 public Collection<V> values()
2053 if (values == null)
2054 values = singleton(v);
2055 return values;
2059 * Obvious string.
2061 * @return A string containing the string representations of the key
2062 * and its associated value.
2064 public String toString()
2066 return "{" + k + "=" + v + "}";
2068 } // class SingletonMap
2071 * Sort a list according to the natural ordering of its elements. The list
2072 * must be modifiable, but can be of fixed size. The sort algorithm is
2073 * precisely that used by Arrays.sort(Object[]), which offers guaranteed
2074 * nlog(n) performance. This implementation dumps the list into an array,
2075 * sorts the array, and then iterates over the list setting each element from
2076 * the array.
2078 * @param l the List to sort (<code>null</code> not permitted)
2079 * @throws ClassCastException if some items are not mutually comparable
2080 * @throws UnsupportedOperationException if the List is not modifiable
2081 * @throws NullPointerException if the list is <code>null</code>, or contains
2082 * some element that is <code>null</code>.
2083 * @see Arrays#sort(Object[])
2085 public static <T extends Comparable<? super T>> void sort(List<T> l)
2087 sort(l, null);
2091 * Sort a list according to a specified Comparator. The list must be
2092 * modifiable, but can be of fixed size. The sort algorithm is precisely that
2093 * used by Arrays.sort(Object[], Comparator), which offers guaranteed
2094 * nlog(n) performance. This implementation dumps the list into an array,
2095 * sorts the array, and then iterates over the list setting each element from
2096 * the array.
2098 * @param l the List to sort (<code>null</code> not permitted)
2099 * @param c the Comparator specifying the ordering for the elements, or
2100 * <code>null</code> for natural ordering
2101 * @throws ClassCastException if c will not compare some pair of items
2102 * @throws UnsupportedOperationException if the List is not modifiable
2103 * @throws NullPointerException if the List is <code>null</code> or
2104 * <code>null</code> is compared by natural ordering (only possible
2105 * when c is <code>null</code>)
2107 * @see Arrays#sort(Object[], Comparator)
2109 public static <T> void sort(List<T> l, Comparator<? super T> c)
2111 T[] a = (T[]) l.toArray();
2112 Arrays.sort(a, c);
2113 ListIterator<T> i = l.listIterator();
2114 for (int pos = 0, alen = a.length; pos < alen; pos++)
2116 i.next();
2117 i.set(a[pos]);
2122 * Swaps the elements at the specified positions within the list. Equal
2123 * positions have no effect.
2125 * @param l the list to work on
2126 * @param i the first index to swap
2127 * @param j the second index
2128 * @throws UnsupportedOperationException if list.set is not supported
2129 * @throws IndexOutOfBoundsException if either i or j is &lt; 0 or &gt;=
2130 * list.size()
2131 * @since 1.4
2133 public static void swap(List<?> l, int i, int j)
2135 List<Object> list = (List<Object>) l;
2136 list.set(i, list.set(j, list.get(i)));
2141 * Returns a synchronized (thread-safe) collection wrapper backed by the
2142 * given collection. Notice that element access through the iterators
2143 * is thread-safe, but if the collection can be structurally modified
2144 * (adding or removing elements) then you should synchronize around the
2145 * iteration to avoid non-deterministic behavior:<br>
2146 * <pre>
2147 * Collection c = Collections.synchronizedCollection(new Collection(...));
2148 * ...
2149 * synchronized (c)
2151 * Iterator i = c.iterator();
2152 * while (i.hasNext())
2153 * foo(i.next());
2155 * </pre><p>
2157 * Since the collection might be a List or a Set, and those have incompatible
2158 * equals and hashCode requirements, this relies on Object's implementation
2159 * rather than passing those calls on to the wrapped collection. The returned
2160 * Collection implements Serializable, but can only be serialized if
2161 * the collection it wraps is likewise Serializable.
2163 * @param c the collection to wrap
2164 * @return a synchronized view of the collection
2165 * @see Serializable
2167 public static <T> Collection<T> synchronizedCollection(Collection<T> c)
2169 return new SynchronizedCollection<T>(c);
2173 * The implementation of {@link #synchronizedCollection(Collection)}. This
2174 * class name is required for compatibility with Sun's JDK serializability.
2175 * Package visible, so that collections such as the one for
2176 * Hashtable.values() can specify which object to synchronize on.
2178 * @author Eric Blake (ebb9@email.byu.edu)
2180 static class SynchronizedCollection<T>
2181 implements Collection<T>, Serializable
2184 * Compatible with JDK 1.4.
2186 private static final long serialVersionUID = 3053995032091335093L;
2189 * The wrapped collection. Package visible for use by subclasses.
2190 * @serial the real collection
2192 final Collection<T> c;
2195 * The object to synchronize on. When an instance is created via public
2196 * methods, it will be this; but other uses like SynchronizedMap.values()
2197 * must specify another mutex. Package visible for use by subclasses.
2198 * @serial the lock
2200 final Object mutex;
2203 * Wrap a given collection.
2204 * @param c the collection to wrap
2205 * @throws NullPointerException if c is null
2207 SynchronizedCollection(Collection<T> c)
2209 this.c = c;
2210 mutex = this;
2211 if (c == null)
2212 throw new NullPointerException();
2216 * Called only by trusted code to specify the mutex as well as the
2217 * collection.
2218 * @param sync the mutex
2219 * @param c the collection
2221 SynchronizedCollection(Object sync, Collection<T> c)
2223 this.c = c;
2224 mutex = sync;
2228 * Adds the object to the underlying collection, first
2229 * obtaining a lock on the mutex.
2231 * @param o The object to add.
2232 * @return <code>true</code> if the collection was modified as a result
2233 * of this action.
2234 * @throws UnsupportedOperationException if this collection does not
2235 * support the add operation.
2236 * @throws ClassCastException if o cannot be added to this collection due
2237 * to its type.
2238 * @throws NullPointerException if o is null and this collection doesn't
2239 * support the addition of null values.
2240 * @throws IllegalArgumentException if o cannot be added to this
2241 * collection for some other reason.
2243 public boolean add(T o)
2245 synchronized (mutex)
2247 return c.add(o);
2252 * Adds the objects in col to the underlying collection, first
2253 * obtaining a lock on the mutex.
2255 * @param col The collection to take the new objects from.
2256 * @return <code>true</code> if the collection was modified as a result
2257 * of this action.
2258 * @throws UnsupportedOperationException if this collection does not
2259 * support the addAll operation.
2260 * @throws ClassCastException if some element of col cannot be added to this
2261 * collection due to its type.
2262 * @throws NullPointerException if some element of col is null and this
2263 * collection does not support the addition of null values.
2264 * @throws NullPointerException if col itself is null.
2265 * @throws IllegalArgumentException if some element of col cannot be added
2266 * to this collection for some other reason.
2268 public boolean addAll(Collection<? extends T> col)
2270 synchronized (mutex)
2272 return c.addAll(col);
2277 * Removes all objects from the underlying collection,
2278 * first obtaining a lock on the mutex.
2280 * @throws UnsupportedOperationException if this collection does not
2281 * support the clear operation.
2283 public void clear()
2285 synchronized (mutex)
2287 c.clear();
2292 * Checks for the existence of o within the underlying
2293 * collection, first obtaining a lock on the mutex.
2295 * @param o the element to look for.
2296 * @return <code>true</code> if this collection contains at least one
2297 * element e such that <code>o == null ? e == null : o.equals(e)</code>.
2298 * @throws ClassCastException if the type of o is not a valid type for this
2299 * collection.
2300 * @throws NullPointerException if o is null and this collection doesn't
2301 * support null values.
2303 public boolean contains(Object o)
2305 synchronized (mutex)
2307 return c.contains(o);
2312 * Checks for the existence of each object in cl
2313 * within the underlying collection, first obtaining
2314 * a lock on the mutex.
2316 * @param c1 the collection to test for.
2317 * @return <code>true</code> if for every element o in c, contains(o)
2318 * would return <code>true</code>.
2319 * @throws ClassCastException if the type of any element in cl is not a valid
2320 * type for this collection.
2321 * @throws NullPointerException if some element of cl is null and this
2322 * collection does not support null values.
2323 * @throws NullPointerException if cl itself is null.
2325 public boolean containsAll(Collection<?> c1)
2327 synchronized (mutex)
2329 return c.containsAll(c1);
2334 * Returns <code>true</code> if there are no objects in the underlying
2335 * collection. A lock on the mutex is obtained before the
2336 * check is performed.
2338 * @return <code>true</code> if this collection contains no elements.
2340 public boolean isEmpty()
2342 synchronized (mutex)
2344 return c.isEmpty();
2349 * Returns a synchronized iterator wrapper around the underlying
2350 * collection's iterator. A lock on the mutex is obtained before
2351 * retrieving the collection's iterator.
2353 * @return An iterator over the elements in the underlying collection,
2354 * which returns each element in any order.
2356 public Iterator<T> iterator()
2358 synchronized (mutex)
2360 return new SynchronizedIterator<T>(mutex, c.iterator());
2365 * Removes the specified object from the underlying collection,
2366 * first obtaining a lock on the mutex.
2368 * @param o The object to remove.
2369 * @return <code>true</code> if the collection changed as a result of this call, that is,
2370 * if the collection contained at least one occurrence of o.
2371 * @throws UnsupportedOperationException if this collection does not
2372 * support the remove operation.
2373 * @throws ClassCastException if the type of o is not a valid type
2374 * for this collection.
2375 * @throws NullPointerException if o is null and the collection doesn't
2376 * support null values.
2378 public boolean remove(Object o)
2380 synchronized (mutex)
2382 return c.remove(o);
2387 * Removes all elements, e, of the underlying
2388 * collection for which <code>col.contains(e)</code>
2389 * returns <code>true</code>. A lock on the mutex is obtained
2390 * before the operation proceeds.
2392 * @param col The collection of objects to be removed.
2393 * @return <code>true</code> if this collection was modified as a result of this call.
2394 * @throws UnsupportedOperationException if this collection does not
2395 * support the removeAll operation.
2396 * @throws ClassCastException if the type of any element in c is not a valid
2397 * type for this collection.
2398 * @throws NullPointerException if some element of c is null and this
2399 * collection does not support removing null values.
2400 * @throws NullPointerException if c itself is null.
2402 public boolean removeAll(Collection<?> col)
2404 synchronized (mutex)
2406 return c.removeAll(col);
2411 * Retains all elements, e, of the underlying
2412 * collection for which <code>col.contains(e)</code>
2413 * returns <code>true</code>. That is, every element that doesn't
2414 * exist in col is removed. A lock on the mutex is obtained
2415 * before the operation proceeds.
2417 * @param col The collection of objects to be removed.
2418 * @return <code>true</code> if this collection was modified as a result of this call.
2419 * @throws UnsupportedOperationException if this collection does not
2420 * support the removeAll operation.
2421 * @throws ClassCastException if the type of any element in c is not a valid
2422 * type for this collection.
2423 * @throws NullPointerException if some element of c is null and this
2424 * collection does not support removing null values.
2425 * @throws NullPointerException if c itself is null.
2427 public boolean retainAll(Collection<?> col)
2429 synchronized (mutex)
2431 return c.retainAll(col);
2436 * Retrieves the size of the underlying collection.
2437 * A lock on the mutex is obtained before the collection
2438 * is accessed.
2440 * @return The size of the collection.
2442 public int size()
2444 synchronized (mutex)
2446 return c.size();
2451 * Returns an array containing each object within the underlying
2452 * collection. A lock is obtained on the mutex before the collection
2453 * is accessed.
2455 * @return An array of objects, matching the collection in size. The
2456 * elements occur in any order.
2458 public Object[] toArray()
2460 synchronized (mutex)
2462 return c.toArray();
2467 * Copies the elements in the underlying collection to the supplied
2468 * array. If <code>a.length < size()</code>, a new array of the
2469 * same run-time type is created, with a size equal to that of
2470 * the collection. If <code>a.length > size()</code>, then the
2471 * elements from 0 to <code>size() - 1</code> contain the elements
2472 * from this collection. The following element is set to null
2473 * to indicate the end of the collection objects. However, this
2474 * only makes a difference if null is not a permitted value within
2475 * the collection.
2476 * Before the copying takes place, a lock is obtained on the mutex.
2478 * @param a An array to copy elements to.
2479 * @return An array containing the elements of the underlying collection.
2480 * @throws ArrayStoreException if the type of any element of the
2481 * collection is not a subtype of the element type of a.
2483 public <T> T[] toArray(T[] a)
2485 synchronized (mutex)
2487 return c.toArray(a);
2492 * Returns a string representation of the underlying collection.
2493 * A lock is obtained on the mutex before the string is created.
2495 * @return A string representation of the collection.
2497 public String toString()
2499 synchronized (mutex)
2501 return c.toString();
2504 } // class SynchronizedCollection
2507 * The implementation of the various iterator methods in the
2508 * synchronized classes. These iterators must "sync" on the same object
2509 * as the collection they iterate over.
2511 * @author Eric Blake (ebb9@email.byu.edu)
2513 private static class SynchronizedIterator<T> implements Iterator<T>
2516 * The object to synchronize on. Package visible for use by subclass.
2518 final Object mutex;
2521 * The wrapped iterator.
2523 private final Iterator<T> i;
2526 * Only trusted code creates a wrapper, with the specified sync.
2527 * @param sync the mutex
2528 * @param i the wrapped iterator
2530 SynchronizedIterator(Object sync, Iterator<T> i)
2532 this.i = i;
2533 mutex = sync;
2537 * Retrieves the next object in the underlying collection.
2538 * A lock is obtained on the mutex before the collection is accessed.
2540 * @return The next object in the collection.
2541 * @throws NoSuchElementException if there are no more elements
2543 public T next()
2545 synchronized (mutex)
2547 return i.next();
2552 * Returns <code>true</code> if objects can still be retrieved from the iterator
2553 * using <code>next()</code>. A lock is obtained on the mutex before
2554 * the collection is accessed.
2556 * @return <code>true</code> if at least one element is still to be returned by
2557 * <code>next()</code>.
2559 public boolean hasNext()
2561 synchronized (mutex)
2563 return i.hasNext();
2568 * Removes the object that was last returned by <code>next()</code>
2569 * from the underlying collection. Only one call to this method is
2570 * allowed per call to the <code>next()</code> method, and it does
2571 * not affect the value that will be returned by <code>next()</code>.
2572 * Thus, if element n was retrieved from the collection by
2573 * <code>next()</code>, it is this element that gets removed.
2574 * Regardless of whether this takes place or not, element n+1 is
2575 * still returned on the subsequent <code>next()</code> call.
2577 * @throws IllegalStateException if next has not yet been called or remove
2578 * has already been called since the last call to next.
2579 * @throws UnsupportedOperationException if this Iterator does not support
2580 * the remove operation.
2582 public void remove()
2584 synchronized (mutex)
2586 i.remove();
2589 } // class SynchronizedIterator
2592 * Returns a synchronized (thread-safe) list wrapper backed by the
2593 * given list. Notice that element access through the iterators
2594 * is thread-safe, but if the list can be structurally modified
2595 * (adding or removing elements) then you should synchronize around the
2596 * iteration to avoid non-deterministic behavior:<br>
2597 * <pre>
2598 * List l = Collections.synchronizedList(new List(...));
2599 * ...
2600 * synchronized (l)
2602 * Iterator i = l.iterator();
2603 * while (i.hasNext())
2604 * foo(i.next());
2606 * </pre><p>
2608 * The returned List implements Serializable, but can only be serialized if
2609 * the list it wraps is likewise Serializable. In addition, if the wrapped
2610 * list implements RandomAccess, this does too.
2612 * @param l the list to wrap
2613 * @return a synchronized view of the list
2614 * @see Serializable
2615 * @see RandomAccess
2617 public static <T> List<T> synchronizedList(List<T> l)
2619 if (l instanceof RandomAccess)
2620 return new SynchronizedRandomAccessList<T>(l);
2621 return new SynchronizedList<T>(l);
2625 * The implementation of {@link #synchronizedList(List)} for sequential
2626 * lists. This class name is required for compatibility with Sun's JDK
2627 * serializability. Package visible, so that lists such as Vector.subList()
2628 * can specify which object to synchronize on.
2630 * @author Eric Blake (ebb9@email.byu.edu)
2632 static class SynchronizedList<T> extends SynchronizedCollection<T>
2633 implements List<T>
2636 * Compatible with JDK 1.4.
2638 private static final long serialVersionUID = -7754090372962971524L;
2641 * The wrapped list; stored both here and in the superclass to avoid
2642 * excessive casting. Package visible for use by subclass.
2643 * @serial the wrapped list
2645 final List<T> list;
2648 * Wrap a given list.
2649 * @param l the list to wrap
2650 * @throws NullPointerException if l is null
2652 SynchronizedList(List<T> l)
2654 super(l);
2655 list = l;
2659 * Called only by trusted code to specify the mutex as well as the list.
2660 * @param sync the mutex
2661 * @param l the list
2663 SynchronizedList(Object sync, List<T> l)
2665 super(sync, l);
2666 list = l;
2670 * Insert an element into the underlying list at a given position (optional
2671 * operation). This shifts all existing elements from that position to the
2672 * end one index to the right. This version of add has no return, since it is
2673 * assumed to always succeed if there is no exception. Before the
2674 * addition takes place, a lock is obtained on the mutex.
2676 * @param index the location to insert the item
2677 * @param o the object to insert
2678 * @throws UnsupportedOperationException if this list does not support the
2679 * add operation
2680 * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
2681 * @throws ClassCastException if o cannot be added to this list due to its
2682 * type
2683 * @throws IllegalArgumentException if o cannot be added to this list for
2684 * some other reason
2685 * @throws NullPointerException if o is null and this list doesn't support
2686 * the addition of null values.
2688 public void add(int index, T o)
2690 synchronized (mutex)
2692 list.add(index, o);
2697 * Add the contents of a collection to the underlying list at the given
2698 * index (optional operation). If the list imposes restraints on what
2699 * can be inserted, such as no null elements, this should be documented.
2700 * A lock is obtained on the mutex before any of the elements are added.
2702 * @param index the index at which to insert
2703 * @param c the collection to add
2704 * @return <code>true</code>, as defined by Collection for a modified list
2705 * @throws UnsupportedOperationException if this list does not support the
2706 * add operation
2707 * @throws ClassCastException if o cannot be added to this list due to its
2708 * type
2709 * @throws IllegalArgumentException if o cannot be added to this list for
2710 * some other reason
2711 * @throws NullPointerException if o is null and this list doesn't support
2712 * the addition of null values.
2714 public boolean addAll(int index, Collection<? extends T> c)
2716 synchronized (mutex)
2718 return list.addAll(index, c);
2723 * Tests whether the underlying list is equal to the supplied object.
2724 * The object is deemed to be equal if it is also a <code>List</code>
2725 * of equal size and with the same elements (i.e. each element, e1,
2726 * in list, l1, and each element, e2, in l2, must return <code>true</code> for
2727 * <code>e1 == null ? e2 == null : e1.equals(e2)</code>. Before the
2728 * comparison is made, a lock is obtained on the mutex.
2730 * @param o The object to test for equality with the underlying list.
2731 * @return <code>true</code> if o is equal to the underlying list under the above
2732 * definition.
2734 public boolean equals(Object o)
2736 synchronized (mutex)
2738 return list.equals(o);
2743 * Retrieves the object at the specified index. A lock
2744 * is obtained on the mutex before the list is accessed.
2746 * @param index the index of the element to be returned
2747 * @return the element at index index in this list
2748 * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
2750 public T get(int index)
2752 synchronized (mutex)
2754 return list.get(index);
2759 * Obtains a hashcode for the underlying list, first obtaining
2760 * a lock on the mutex. The calculation of the hashcode is
2761 * detailed in the documentation for the <code>List</code>
2762 * interface.
2764 * @return The hashcode of the underlying list.
2765 * @see List#hashCode()
2767 public int hashCode()
2769 synchronized (mutex)
2771 return list.hashCode();
2776 * Obtain the first index at which a given object is to be found in the
2777 * underlying list. A lock is obtained on the mutex before the list is
2778 * accessed.
2780 * @param o the object to search for
2781 * @return the least integer n such that <code>o == null ? get(n) == null :
2782 * o.equals(get(n))</code>, or -1 if there is no such index.
2783 * @throws ClassCastException if the type of o is not a valid
2784 * type for this list.
2785 * @throws NullPointerException if o is null and this
2786 * list does not support null values.
2789 public int indexOf(Object o)
2791 synchronized (mutex)
2793 return list.indexOf(o);
2798 * Obtain the last index at which a given object is to be found in this
2799 * underlying list. A lock is obtained on the mutex before the list
2800 * is accessed.
2802 * @return the greatest integer n such that <code>o == null ? get(n) == null
2803 * : o.equals(get(n))</code>, or -1 if there is no such index.
2804 * @throws ClassCastException if the type of o is not a valid
2805 * type for this list.
2806 * @throws NullPointerException if o is null and this
2807 * list does not support null values.
2809 public int lastIndexOf(Object o)
2811 synchronized (mutex)
2813 return list.lastIndexOf(o);
2818 * Retrieves a synchronized wrapper around the underlying list's
2819 * list iterator. A lock is obtained on the mutex before the
2820 * list iterator is retrieved.
2822 * @return A list iterator over the elements in the underlying list.
2823 * The list iterator allows additional list-specific operations
2824 * to be performed, in addition to those supplied by the
2825 * standard iterator.
2827 public ListIterator<T> listIterator()
2829 synchronized (mutex)
2831 return new SynchronizedListIterator<T>(mutex, list.listIterator());
2836 * Retrieves a synchronized wrapper around the underlying list's
2837 * list iterator. A lock is obtained on the mutex before the
2838 * list iterator is retrieved. The iterator starts at the
2839 * index supplied, leading to the element at that index being
2840 * the first one returned by <code>next()</code>. Calling
2841 * <code>previous()</code> from this initial position returns
2842 * index - 1.
2844 * @param index the position, between 0 and size() inclusive, to begin the
2845 * iteration from
2846 * @return A list iterator over the elements in the underlying list.
2847 * The list iterator allows additional list-specific operations
2848 * to be performed, in addition to those supplied by the
2849 * standard iterator.
2850 * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
2852 public ListIterator<T> listIterator(int index)
2854 synchronized (mutex)
2856 return new SynchronizedListIterator<T>(mutex,
2857 list.listIterator(index));
2862 * Remove the element at a given position in the underlying list (optional
2863 * operation). All remaining elements are shifted to the left to fill the gap.
2864 * A lock on the mutex is obtained before the element is removed.
2866 * @param index the position within the list of the object to remove
2867 * @return the object that was removed
2868 * @throws UnsupportedOperationException if this list does not support the
2869 * remove operation
2870 * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
2872 public T remove(int index)
2874 synchronized (mutex)
2876 return list.remove(index);
2881 * Replace an element of the underlying list with another object (optional
2882 * operation). A lock is obtained on the mutex before the element is
2883 * replaced.
2885 * @param index the position within this list of the element to be replaced
2886 * @param o the object to replace it with
2887 * @return the object that was replaced
2888 * @throws UnsupportedOperationException if this list does not support the
2889 * set operation.
2890 * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
2891 * @throws ClassCastException if o cannot be added to this list due to its
2892 * type
2893 * @throws IllegalArgumentException if o cannot be added to this list for
2894 * some other reason
2895 * @throws NullPointerException if o is null and this
2896 * list does not support null values.
2898 public T set(int index, T o)
2900 synchronized (mutex)
2902 return list.set(index, o);
2907 * Obtain a List view of a subsection of the underlying list, from fromIndex
2908 * (inclusive) to toIndex (exclusive). If the two indices are equal, the
2909 * sublist is empty. The returned list should be modifiable if and only
2910 * if this list is modifiable. Changes to the returned list should be
2911 * reflected in this list. If this list is structurally modified in
2912 * any way other than through the returned list, the result of any subsequent
2913 * operations on the returned list is undefined. A lock is obtained
2914 * on the mutex before the creation of the sublist. The returned list
2915 * is also synchronized, using the same mutex.
2917 * @param fromIndex the index that the returned list should start from
2918 * (inclusive)
2919 * @param toIndex the index that the returned list should go to (exclusive)
2920 * @return a List backed by a subsection of this list
2921 * @throws IndexOutOfBoundsException if fromIndex &lt; 0
2922 * || toIndex &gt; size() || fromIndex &gt; toIndex
2924 public List<T> subList(int fromIndex, int toIndex)
2926 synchronized (mutex)
2928 return new SynchronizedList<T>(mutex,
2929 list.subList(fromIndex, toIndex));
2932 } // class SynchronizedList
2935 * The implementation of {@link #synchronizedList(List)} for random-access
2936 * lists. This class name is required for compatibility with Sun's JDK
2937 * serializability.
2939 * @author Eric Blake (ebb9@email.byu.edu)
2941 private static final class SynchronizedRandomAccessList<T>
2942 extends SynchronizedList<T> implements RandomAccess
2945 * Compatible with JDK 1.4.
2947 private static final long serialVersionUID = 1530674583602358482L;
2950 * Wrap a given list.
2951 * @param l the list to wrap
2952 * @throws NullPointerException if l is null
2954 SynchronizedRandomAccessList(List<T> l)
2956 super(l);
2960 * Called only by trusted code to specify the mutex as well as the
2961 * collection.
2962 * @param sync the mutex
2963 * @param l the list
2965 SynchronizedRandomAccessList(Object sync, List<T> l)
2967 super(sync, l);
2971 * Obtain a List view of a subsection of the underlying list, from fromIndex
2972 * (inclusive) to toIndex (exclusive). If the two indices are equal, the
2973 * sublist is empty. The returned list should be modifiable if and only
2974 * if this list is modifiable. Changes to the returned list should be
2975 * reflected in this list. If this list is structurally modified in
2976 * any way other than through the returned list, the result of any subsequent
2977 * operations on the returned list is undefined. A lock is obtained
2978 * on the mutex before the creation of the sublist. The returned list
2979 * is also synchronized, using the same mutex. Random accessibility
2980 * is also extended to the new list.
2982 * @param fromIndex the index that the returned list should start from
2983 * (inclusive)
2984 * @param toIndex the index that the returned list should go to (exclusive)
2985 * @return a List backed by a subsection of this list
2986 * @throws IndexOutOfBoundsException if fromIndex &lt; 0
2987 * || toIndex &gt; size() || fromIndex &gt; toIndex
2989 public List<T> subList(int fromIndex, int toIndex)
2991 synchronized (mutex)
2993 return new SynchronizedRandomAccessList<T>(mutex,
2994 list.subList(fromIndex,
2995 toIndex));
2998 } // class SynchronizedRandomAccessList
3001 * The implementation of {@link SynchronizedList#listIterator()}. This
3002 * iterator must "sync" on the same object as the list it iterates over.
3004 * @author Eric Blake (ebb9@email.byu.edu)
3006 private static final class SynchronizedListIterator<T>
3007 extends SynchronizedIterator<T> implements ListIterator<T>
3010 * The wrapped iterator, stored both here and in the superclass to
3011 * avoid excessive casting.
3013 private final ListIterator<T> li;
3016 * Only trusted code creates a wrapper, with the specified sync.
3017 * @param sync the mutex
3018 * @param li the wrapped iterator
3020 SynchronizedListIterator(Object sync, ListIterator<T> li)
3022 super(sync, li);
3023 this.li = li;
3027 * Insert an element into the underlying list at the current position of
3028 * the iterator (optional operation). The element is inserted in between
3029 * the element that would be returned by <code>previous()</code> and the
3030 * element that would be returned by <code>next()</code>. After the
3031 * insertion, a subsequent call to next is unaffected, but
3032 * a call to previous returns the item that was added. The values returned
3033 * by nextIndex() and previousIndex() are incremented. A lock is obtained
3034 * on the mutex before the addition takes place.
3036 * @param o the object to insert into the list
3037 * @throws ClassCastException if the object is of a type which cannot be added
3038 * to this list.
3039 * @throws IllegalArgumentException if some other aspect of the object stops
3040 * it being added to this list.
3041 * @throws UnsupportedOperationException if this ListIterator does not
3042 * support the add operation.
3044 public void add(T o)
3046 synchronized (mutex)
3048 li.add(o);
3053 * Tests whether there are elements remaining in the underlying list
3054 * in the reverse direction. In other words, <code>previous()</code>
3055 * will not fail with a NoSuchElementException. A lock is obtained
3056 * on the mutex before the check takes place.
3058 * @return <code>true</code> if the list continues in the reverse direction
3060 public boolean hasPrevious()
3062 synchronized (mutex)
3064 return li.hasPrevious();
3069 * Find the index of the element that would be returned by a call to
3070 * <code>next()</code>. If hasNext() returns <code>false</code>, this
3071 * returns the list size. A lock is obtained on the mutex before the
3072 * query takes place.
3074 * @return the index of the element that would be returned by next()
3076 public int nextIndex()
3078 synchronized (mutex)
3080 return li.nextIndex();
3085 * Obtain the previous element from the underlying list. Repeated
3086 * calls to previous may be used to iterate backwards over the entire list,
3087 * or calls to next and previous may be used together to go forwards and
3088 * backwards. Alternating calls to next and previous will return the same
3089 * element. A lock is obtained on the mutex before the object is retrieved.
3091 * @return the next element in the list in the reverse direction
3092 * @throws NoSuchElementException if there are no more elements
3094 public T previous()
3096 synchronized (mutex)
3098 return li.previous();
3103 * Find the index of the element that would be returned by a call to
3104 * previous. If hasPrevious() returns <code>false</code>, this returns -1.
3105 * A lock is obtained on the mutex before the query takes place.
3107 * @return the index of the element that would be returned by previous()
3109 public int previousIndex()
3111 synchronized (mutex)
3113 return li.previousIndex();
3118 * Replace the element last returned by a call to <code>next()</code> or
3119 * <code>previous()</code> with a given object (optional operation). This
3120 * method may only be called if neither <code>add()</code> nor
3121 * <code>remove()</code> have been called since the last call to
3122 * <code>next()</code> or <code>previous</code>. A lock is obtained
3123 * on the mutex before the list is modified.
3125 * @param o the object to replace the element with
3126 * @throws ClassCastException the object is of a type which cannot be added
3127 * to this list
3128 * @throws IllegalArgumentException some other aspect of the object stops
3129 * it being added to this list
3130 * @throws IllegalStateException if neither next or previous have been
3131 * called, or if add or remove has been called since the last call
3132 * to next or previous
3133 * @throws UnsupportedOperationException if this ListIterator does not
3134 * support the set operation
3136 public void set(T o)
3138 synchronized (mutex)
3140 li.set(o);
3143 } // class SynchronizedListIterator
3146 * Returns a synchronized (thread-safe) map wrapper backed by the given
3147 * map. Notice that element access through the collection views and their
3148 * iterators are thread-safe, but if the map can be structurally modified
3149 * (adding or removing elements) then you should synchronize around the
3150 * iteration to avoid non-deterministic behavior:<br>
3151 * <pre>
3152 * Map m = Collections.synchronizedMap(new Map(...));
3153 * ...
3154 * Set s = m.keySet(); // safe outside a synchronized block
3155 * synchronized (m) // synch on m, not s
3157 * Iterator i = s.iterator();
3158 * while (i.hasNext())
3159 * foo(i.next());
3161 * </pre><p>
3163 * The returned Map implements Serializable, but can only be serialized if
3164 * the map it wraps is likewise Serializable.
3166 * @param m the map to wrap
3167 * @return a synchronized view of the map
3168 * @see Serializable
3170 public static <K, V> Map<K, V> synchronizedMap(Map<K, V> m)
3172 return new SynchronizedMap<K, V>(m);
3176 * The implementation of {@link #synchronizedMap(Map)}. This
3177 * class name is required for compatibility with Sun's JDK serializability.
3179 * @author Eric Blake (ebb9@email.byu.edu)
3181 private static class SynchronizedMap<K, V> implements Map<K, V>, Serializable
3184 * Compatible with JDK 1.4.
3186 private static final long serialVersionUID = 1978198479659022715L;
3189 * The wrapped map.
3190 * @serial the real map
3192 private final Map<K, V> m;
3195 * The object to synchronize on. When an instance is created via public
3196 * methods, it will be this; but other uses like
3197 * SynchronizedSortedMap.subMap() must specify another mutex. Package
3198 * visible for use by subclass.
3199 * @serial the lock
3201 final Object mutex;
3204 * Cache the entry set.
3206 private transient Set<Map.Entry<K, V>> entries;
3209 * Cache the key set.
3211 private transient Set<K> keys;
3214 * Cache the value collection.
3216 private transient Collection<V> values;
3219 * Wrap a given map.
3220 * @param m the map to wrap
3221 * @throws NullPointerException if m is null
3223 SynchronizedMap(Map<K, V> m)
3225 this.m = m;
3226 mutex = this;
3227 if (m == null)
3228 throw new NullPointerException();
3232 * Called only by trusted code to specify the mutex as well as the map.
3233 * @param sync the mutex
3234 * @param m the map
3236 SynchronizedMap(Object sync, Map<K, V> m)
3238 this.m = m;
3239 mutex = sync;
3243 * Clears all the entries from the underlying map. A lock is obtained
3244 * on the mutex before the map is cleared.
3246 * @throws UnsupportedOperationException if clear is not supported
3248 public void clear()
3250 synchronized (mutex)
3252 m.clear();
3257 * Returns <code>true</code> if the underlying map contains a entry for the given key.
3258 * A lock is obtained on the mutex before the map is queried.
3260 * @param key the key to search for.
3261 * @return <code>true</code> if the underlying map contains the key.
3262 * @throws ClassCastException if the key is of an inappropriate type.
3263 * @throws NullPointerException if key is <code>null</code> but the map
3264 * does not permit null keys.
3266 public boolean containsKey(Object key)
3268 synchronized (mutex)
3270 return m.containsKey(key);
3275 * Returns <code>true</code> if the underlying map contains at least one entry with the
3276 * given value. In other words, returns <code>true</code> if a value v exists where
3277 * <code>(value == null ? v == null : value.equals(v))</code>. This usually
3278 * requires linear time. A lock is obtained on the mutex before the map
3279 * is queried.
3281 * @param value the value to search for
3282 * @return <code>true</code> if the map contains the value
3283 * @throws ClassCastException if the type of the value is not a valid type
3284 * for this map.
3285 * @throws NullPointerException if the value is null and the map doesn't
3286 * support null values.
3288 public boolean containsValue(Object value)
3290 synchronized (mutex)
3292 return m.containsValue(value);
3296 // This is one of the ickiest cases of nesting I've ever seen. It just
3297 // means "return a SynchronizedSet, except that the iterator() method
3298 // returns an SynchronizedIterator whose next() method returns a
3299 // synchronized wrapper around its normal return value".
3300 public Set<Map.Entry<K, V>> entrySet()
3302 // Define this here to spare some nesting.
3303 class SynchronizedMapEntry<K, V> implements Map.Entry<K, V>
3305 final Map.Entry<K, V> e;
3306 SynchronizedMapEntry(Map.Entry<K, V> o)
3308 e = o;
3312 * Returns <code>true</code> if the object, o, implements <code>Map.Entry</code>
3313 * with the same key and value as the underlying entry. A lock is
3314 * obtained on the mutex before the comparison takes place.
3316 * @param o The object to compare with this entry.
3317 * @return <code>true</code> if o is equivalent to the underlying map entry.
3319 public boolean equals(Object o)
3321 synchronized (mutex)
3323 return e.equals(o);
3328 * Returns the key used in the underlying map entry. A lock is obtained
3329 * on the mutex before the key is retrieved.
3331 * @return The key of the underlying map entry.
3333 public K getKey()
3335 synchronized (mutex)
3337 return e.getKey();
3342 * Returns the value used in the underlying map entry. A lock is obtained
3343 * on the mutex before the value is retrieved.
3345 * @return The value of the underlying map entry.
3347 public V getValue()
3349 synchronized (mutex)
3351 return e.getValue();
3356 * Computes the hash code for the underlying map entry.
3357 * This computation is described in the documentation for the
3358 * <code>Map</code> interface. A lock is obtained on the mutex
3359 * before the underlying map is accessed.
3361 * @return The hash code of the underlying map entry.
3362 * @see Map#hashCode()
3364 public int hashCode()
3366 synchronized (mutex)
3368 return e.hashCode();
3373 * Replaces the value in the underlying map entry with the specified
3374 * object (optional operation). A lock is obtained on the mutex
3375 * before the map is altered. The map entry, in turn, will alter
3376 * the underlying map object. The operation is undefined if the
3377 * <code>remove()</code> method of the iterator has been called
3378 * beforehand.
3380 * @param value the new value to store
3381 * @return the old value
3382 * @throws UnsupportedOperationException if the operation is not supported.
3383 * @throws ClassCastException if the value is of the wrong type.
3384 * @throws IllegalArgumentException if something about the value
3385 * prevents it from existing in this map.
3386 * @throws NullPointerException if the map forbids null values.
3388 public V setValue(V value)
3390 synchronized (mutex)
3392 return e.setValue(value);
3397 * Returns a textual representation of the underlying map entry.
3398 * A lock is obtained on the mutex before the entry is accessed.
3400 * @return The contents of the map entry in <code>String</code> form.
3402 public String toString()
3404 synchronized (mutex)
3406 return e.toString();
3409 } // class SynchronizedMapEntry
3411 // Now the actual code.
3412 if (entries == null)
3413 synchronized (mutex)
3415 entries = new SynchronizedSet<Map.Entry<K, V>>(mutex, m.entrySet())
3418 * Returns an iterator over the set. The iterator has no specific order,
3419 * unless further specified. A lock is obtained on the set's mutex
3420 * before the iterator is created. The created iterator is also
3421 * thread-safe.
3423 * @return A synchronized set iterator.
3425 public Iterator<Map.Entry<K, V>> iterator()
3427 synchronized (super.mutex)
3429 return new SynchronizedIterator<Map.Entry<K, V>>(super.mutex,
3430 c.iterator())
3433 * Retrieves the next map entry from the iterator.
3434 * A lock is obtained on the iterator's mutex before
3435 * the entry is created. The new map entry is enclosed in
3436 * a thread-safe wrapper.
3438 * @return A synchronized map entry.
3440 public Map.Entry<K, V> next()
3442 synchronized (super.mutex)
3444 return new SynchronizedMapEntry<K, V>(super.next());
3452 return entries;
3456 * Returns <code>true</code> if the object, o, is also an instance
3457 * of <code>Map</code> and contains an equivalent
3458 * entry set to that of the underlying map. A lock
3459 * is obtained on the mutex before the objects are
3460 * compared.
3462 * @param o The object to compare.
3463 * @return <code>true</code> if o and the underlying map are equivalent.
3465 public boolean equals(Object o)
3467 synchronized (mutex)
3469 return m.equals(o);
3474 * Returns the value associated with the given key, or null
3475 * if no such mapping exists. An ambiguity exists with maps
3476 * that accept null values as a return value of null could
3477 * be due to a non-existent mapping or simply a null value
3478 * for that key. To resolve this, <code>containsKey</code>
3479 * should be used. A lock is obtained on the mutex before
3480 * the value is retrieved from the underlying map.
3482 * @param key The key of the required mapping.
3483 * @return The value associated with the given key, or
3484 * null if no such mapping exists.
3485 * @throws ClassCastException if the key is an inappropriate type.
3486 * @throws NullPointerException if this map does not accept null keys.
3488 public V get(Object key)
3490 synchronized (mutex)
3492 return m.get(key);
3497 * Calculates the hash code of the underlying map as the
3498 * sum of the hash codes of all entries. A lock is obtained
3499 * on the mutex before the hash code is computed.
3501 * @return The hash code of the underlying map.
3503 public int hashCode()
3505 synchronized (mutex)
3507 return m.hashCode();
3512 * Returns <code>true</code> if the underlying map contains no entries.
3513 * A lock is obtained on the mutex before the map is examined.
3515 * @return <code>true</code> if the map is empty.
3517 public boolean isEmpty()
3519 synchronized (mutex)
3521 return m.isEmpty();
3526 * Returns a thread-safe set view of the keys in the underlying map. The
3527 * set is backed by the map, so that changes in one show up in the other.
3528 * Modifications made while an iterator is in progress cause undefined
3529 * behavior. If the set supports removal, these methods remove the
3530 * underlying mapping from the map: <code>Iterator.remove</code>,
3531 * <code>Set.remove</code>, <code>removeAll</code>, <code>retainAll</code>,
3532 * and <code>clear</code>. Element addition, via <code>add</code> or
3533 * <code>addAll</code>, is not supported via this set. A lock is obtained
3534 * on the mutex before the set is created.
3536 * @return A synchronized set containing the keys of the underlying map.
3538 public Set<K> keySet()
3540 if (keys == null)
3541 synchronized (mutex)
3543 keys = new SynchronizedSet<K>(mutex, m.keySet());
3545 return keys;
3549 * Associates the given key to the given value (optional operation). If the
3550 * underlying map already contains the key, its value is replaced. Be aware
3551 * that in a map that permits <code>null</code> values, a null return does not
3552 * always imply that the mapping was created. A lock is obtained on the mutex
3553 * before the modification is made.
3555 * @param key the key to map.
3556 * @param value the value to be mapped.
3557 * @return the previous value of the key, or null if there was no mapping
3558 * @throws UnsupportedOperationException if the operation is not supported
3559 * @throws ClassCastException if the key or value is of the wrong type
3560 * @throws IllegalArgumentException if something about this key or value
3561 * prevents it from existing in this map
3562 * @throws NullPointerException if either the key or the value is null,
3563 * and the map forbids null keys or values
3564 * @see #containsKey(Object)
3566 public V put(K key, V value)
3568 synchronized (mutex)
3570 return m.put(key, value);
3575 * Copies all entries of the given map to the underlying one (optional
3576 * operation). If the map already contains a key, its value is replaced.
3577 * A lock is obtained on the mutex before the operation proceeds.
3579 * @param map the mapping to load into this map
3580 * @throws UnsupportedOperationException if the operation is not supported
3581 * @throws ClassCastException if a key or value is of the wrong type
3582 * @throws IllegalArgumentException if something about a key or value
3583 * prevents it from existing in this map
3584 * @throws NullPointerException if the map forbids null keys or values, or
3585 * if <code>m</code> is null.
3586 * @see #put(Object, Object)
3588 public void putAll(Map<? extends K, ? extends V> map)
3590 synchronized (mutex)
3592 m.putAll(map);
3597 * Removes the mapping for the key, o, if present (optional operation). If
3598 * the key is not present, this returns null. Note that maps which permit
3599 * null values may also return null if the key was removed. A prior
3600 * <code>containsKey()</code> check is required to avoid this ambiguity.
3601 * Before the mapping is removed, a lock is obtained on the mutex.
3603 * @param o the key to remove
3604 * @return the value the key mapped to, or null if not present
3605 * @throws UnsupportedOperationException if deletion is unsupported
3606 * @throws NullPointerException if the key is null and this map doesn't
3607 * support null keys.
3608 * @throws ClassCastException if the type of the key is not a valid type
3609 * for this map.
3611 public V remove(Object o)
3613 synchronized (mutex)
3615 return m.remove(o);
3620 * Retrieves the size of the underlying map. A lock
3621 * is obtained on the mutex before access takes place.
3622 * Maps with a size greater than <code>Integer.MAX_VALUE</code>
3623 * return <code>Integer.MAX_VALUE</code> instead.
3625 * @return The size of the underlying map.
3627 public int size()
3629 synchronized (mutex)
3631 return m.size();
3636 * Returns a textual representation of the underlying
3637 * map. A lock is obtained on the mutex before the map
3638 * is accessed.
3640 * @return The map in <code>String</code> form.
3642 public String toString()
3644 synchronized (mutex)
3646 return m.toString();
3651 * Returns a synchronized collection view of the values in the underlying
3652 * map. The collection is backed by the map, so that changes in one show up in
3653 * the other. Modifications made while an iterator is in progress cause
3654 * undefined behavior. If the collection supports removal, these methods
3655 * remove the underlying mapping from the map: <code>Iterator.remove</code>,
3656 * <code>Collection.remove</code>, <code>removeAll</code>,
3657 * <code>retainAll</code>, and <code>clear</code>. Element addition, via
3658 * <code>add</code> or <code>addAll</code>, is not supported via this
3659 * collection. A lock is obtained on the mutex before the collection
3660 * is created.
3662 * @return the collection of all values in the underlying map.
3664 public Collection<V> values()
3666 if (values == null)
3667 synchronized (mutex)
3669 values = new SynchronizedCollection<V>(mutex, m.values());
3671 return values;
3673 } // class SynchronizedMap
3676 * Returns a synchronized (thread-safe) set wrapper backed by the given
3677 * set. Notice that element access through the iterator is thread-safe, but
3678 * if the set can be structurally modified (adding or removing elements)
3679 * then you should synchronize around the iteration to avoid
3680 * non-deterministic behavior:<br>
3681 * <pre>
3682 * Set s = Collections.synchronizedSet(new Set(...));
3683 * ...
3684 * synchronized (s)
3686 * Iterator i = s.iterator();
3687 * while (i.hasNext())
3688 * foo(i.next());
3690 * </pre><p>
3692 * The returned Set implements Serializable, but can only be serialized if
3693 * the set it wraps is likewise Serializable.
3695 * @param s the set to wrap
3696 * @return a synchronized view of the set
3697 * @see Serializable
3699 public static <T> Set<T> synchronizedSet(Set<T> s)
3701 return new SynchronizedSet<T>(s);
3705 * The implementation of {@link #synchronizedSet(Set)}. This class
3706 * name is required for compatibility with Sun's JDK serializability.
3707 * Package visible, so that sets such as Hashtable.keySet()
3708 * can specify which object to synchronize on.
3710 * @author Eric Blake (ebb9@email.byu.edu)
3712 static class SynchronizedSet<T> extends SynchronizedCollection<T>
3713 implements Set<T>
3716 * Compatible with JDK 1.4.
3718 private static final long serialVersionUID = 487447009682186044L;
3721 * Wrap a given set.
3722 * @param s the set to wrap
3723 * @throws NullPointerException if s is null
3725 SynchronizedSet(Set<T> s)
3727 super(s);
3731 * Called only by trusted code to specify the mutex as well as the set.
3732 * @param sync the mutex
3733 * @param s the set
3735 SynchronizedSet(Object sync, Set<T> s)
3737 super(sync, s);
3741 * Returns <code>true</code> if the object, o, is a <code>Set</code>
3742 * of the same size as the underlying set, and contains
3743 * each element, e, which occurs in the underlying set.
3744 * A lock is obtained on the mutex before the comparison
3745 * takes place.
3747 * @param o The object to compare against.
3748 * @return <code>true</code> if o is an equivalent set.
3750 public boolean equals(Object o)
3752 synchronized (mutex)
3754 return c.equals(o);
3759 * Computes the hash code for the underlying set as the
3760 * sum of the hash code of all elements within the set.
3761 * A lock is obtained on the mutex before the computation
3762 * occurs.
3764 * @return The hash code for the underlying set.
3766 public int hashCode()
3768 synchronized (mutex)
3770 return c.hashCode();
3773 } // class SynchronizedSet
3776 * Returns a synchronized (thread-safe) sorted map wrapper backed by the
3777 * given map. Notice that element access through the collection views,
3778 * subviews, and their iterators are thread-safe, but if the map can be
3779 * structurally modified (adding or removing elements) then you should
3780 * synchronize around the iteration to avoid non-deterministic behavior:<br>
3781 * <pre>
3782 * SortedMap m = Collections.synchronizedSortedMap(new SortedMap(...));
3783 * ...
3784 * Set s = m.keySet(); // safe outside a synchronized block
3785 * SortedMap m2 = m.headMap(foo); // safe outside a synchronized block
3786 * Set s2 = m2.keySet(); // safe outside a synchronized block
3787 * synchronized (m) // synch on m, not m2, s or s2
3789 * Iterator i = s.iterator();
3790 * while (i.hasNext())
3791 * foo(i.next());
3792 * i = s2.iterator();
3793 * while (i.hasNext())
3794 * bar(i.next());
3796 * </pre><p>
3798 * The returned SortedMap implements Serializable, but can only be
3799 * serialized if the map it wraps is likewise Serializable.
3801 * @param m the sorted map to wrap
3802 * @return a synchronized view of the sorted map
3803 * @see Serializable
3805 public static <K, V> SortedMap<K, V> synchronizedSortedMap(SortedMap<K, V> m)
3807 return new SynchronizedSortedMap<K, V>(m);
3811 * The implementation of {@link #synchronizedSortedMap(SortedMap)}. This
3812 * class name is required for compatibility with Sun's JDK serializability.
3814 * @author Eric Blake (ebb9@email.byu.edu)
3816 private static final class SynchronizedSortedMap<K, V>
3817 extends SynchronizedMap<K, V>
3818 implements SortedMap<K, V>
3821 * Compatible with JDK 1.4.
3823 private static final long serialVersionUID = -8798146769416483793L;
3826 * The wrapped map; stored both here and in the superclass to avoid
3827 * excessive casting.
3828 * @serial the wrapped map
3830 private final SortedMap<K, V> sm;
3833 * Wrap a given map.
3834 * @param sm the map to wrap
3835 * @throws NullPointerException if sm is null
3837 SynchronizedSortedMap(SortedMap<K, V> sm)
3839 super(sm);
3840 this.sm = sm;
3844 * Called only by trusted code to specify the mutex as well as the map.
3845 * @param sync the mutex
3846 * @param sm the map
3848 SynchronizedSortedMap(Object sync, SortedMap<K, V> sm)
3850 super(sync, sm);
3851 this.sm = sm;
3855 * Returns the comparator used in sorting the underlying map, or null if
3856 * it is the keys' natural ordering. A lock is obtained on the mutex
3857 * before the comparator is retrieved.
3859 * @return the sorting comparator.
3861 public Comparator<? super K> comparator()
3863 synchronized (mutex)
3865 return sm.comparator();
3870 * Returns the first, lowest sorted, key from the underlying map.
3871 * A lock is obtained on the mutex before the map is accessed.
3873 * @return the first key.
3874 * @throws NoSuchElementException if this map is empty.
3876 public K firstKey()
3878 synchronized (mutex)
3880 return sm.firstKey();
3885 * Returns a submap containing the keys from the first
3886 * key (as returned by <code>firstKey()</code>) to
3887 * the key before that specified. The submap supports all
3888 * operations supported by the underlying map and all actions
3889 * taking place on the submap are also reflected in the underlying
3890 * map. A lock is obtained on the mutex prior to submap creation.
3891 * This operation is equivalent to <code>subMap(firstKey(), toKey)</code>.
3892 * The submap retains the thread-safe status of this map.
3894 * @param toKey the exclusive upper range of the submap.
3895 * @return a submap from <code>firstKey()</code> to the
3896 * the key preceding toKey.
3897 * @throws ClassCastException if toKey is not comparable to the underlying
3898 * map's contents.
3899 * @throws IllegalArgumentException if toKey is outside the map's range.
3900 * @throws NullPointerException if toKey is null. but the map does not allow
3901 * null keys.
3903 public SortedMap<K, V> headMap(K toKey)
3905 synchronized (mutex)
3907 return new SynchronizedSortedMap<K, V>(mutex, sm.headMap(toKey));
3912 * Returns the last, highest sorted, key from the underlying map.
3913 * A lock is obtained on the mutex before the map is accessed.
3915 * @return the last key.
3916 * @throws NoSuchElementException if this map is empty.
3918 public K lastKey()
3920 synchronized (mutex)
3922 return sm.lastKey();
3927 * Returns a submap containing the keys from fromKey to
3928 * the key before toKey. The submap supports all
3929 * operations supported by the underlying map and all actions
3930 * taking place on the submap are also reflected in the underlying
3931 * map. A lock is obtained on the mutex prior to submap creation.
3932 * The submap retains the thread-safe status of this map.
3934 * @param fromKey the inclusive lower range of the submap.
3935 * @param toKey the exclusive upper range of the submap.
3936 * @return a submap from fromKey to the key preceding toKey.
3937 * @throws ClassCastException if fromKey or toKey is not comparable
3938 * to the underlying map's contents.
3939 * @throws IllegalArgumentException if fromKey or toKey is outside the map's
3940 * range.
3941 * @throws NullPointerException if fromKey or toKey is null. but the map does
3942 * not allow null keys.
3944 public SortedMap<K, V> subMap(K fromKey, K toKey)
3946 synchronized (mutex)
3948 return new SynchronizedSortedMap<K, V>(mutex,
3949 sm.subMap(fromKey, toKey));
3954 * Returns a submap containing all the keys from fromKey onwards.
3955 * The submap supports all operations supported by the underlying
3956 * map and all actions taking place on the submap are also reflected
3957 * in the underlying map. A lock is obtained on the mutex prior to
3958 * submap creation. The submap retains the thread-safe status of
3959 * this map.
3961 * @param fromKey the inclusive lower range of the submap.
3962 * @return a submap from fromKey to <code>lastKey()</code>.
3963 * @throws ClassCastException if fromKey is not comparable to the underlying
3964 * map's contents.
3965 * @throws IllegalArgumentException if fromKey is outside the map's range.
3966 * @throws NullPointerException if fromKey is null. but the map does not allow
3967 * null keys.
3969 public SortedMap<K, V> tailMap(K fromKey)
3971 synchronized (mutex)
3973 return new SynchronizedSortedMap<K, V>(mutex, sm.tailMap(fromKey));
3976 } // class SynchronizedSortedMap
3979 * Returns a synchronized (thread-safe) sorted set wrapper backed by the
3980 * given set. Notice that element access through the iterator and through
3981 * subviews are thread-safe, but if the set can be structurally modified
3982 * (adding or removing elements) then you should synchronize around the
3983 * iteration to avoid non-deterministic behavior:<br>
3984 * <pre>
3985 * SortedSet s = Collections.synchronizedSortedSet(new SortedSet(...));
3986 * ...
3987 * SortedSet s2 = s.headSet(foo); // safe outside a synchronized block
3988 * synchronized (s) // synch on s, not s2
3990 * Iterator i = s2.iterator();
3991 * while (i.hasNext())
3992 * foo(i.next());
3994 * </pre><p>
3996 * The returned SortedSet implements Serializable, but can only be
3997 * serialized if the set it wraps is likewise Serializable.
3999 * @param s the sorted set to wrap
4000 * @return a synchronized view of the sorted set
4001 * @see Serializable
4003 public static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s)
4005 return new SynchronizedSortedSet<T>(s);
4009 * The implementation of {@link #synchronizedSortedSet(SortedSet)}. This
4010 * class name is required for compatibility with Sun's JDK serializability.
4012 * @author Eric Blake (ebb9@email.byu.edu)
4014 private static final class SynchronizedSortedSet<T>
4015 extends SynchronizedSet<T>
4016 implements SortedSet<T>
4019 * Compatible with JDK 1.4.
4021 private static final long serialVersionUID = 8695801310862127406L;
4024 * The wrapped set; stored both here and in the superclass to avoid
4025 * excessive casting.
4026 * @serial the wrapped set
4028 private final SortedSet<T> ss;
4031 * Wrap a given set.
4032 * @param ss the set to wrap
4033 * @throws NullPointerException if ss is null
4035 SynchronizedSortedSet(SortedSet<T> ss)
4037 super(ss);
4038 this.ss = ss;
4042 * Called only by trusted code to specify the mutex as well as the set.
4043 * @param sync the mutex
4044 * @param ss the set
4046 SynchronizedSortedSet(Object sync, SortedSet<T> ss)
4048 super(sync, ss);
4049 this.ss = ss;
4053 * Returns the comparator used in sorting the underlying set, or null if
4054 * it is the elements' natural ordering. A lock is obtained on the mutex
4055 * before the comparator is retrieved.
4057 * @return the sorting comparator.
4059 public Comparator<? super T> comparator()
4061 synchronized (mutex)
4063 return ss.comparator();
4068 * Returns the first, lowest sorted, element from the underlying set.
4069 * A lock is obtained on the mutex before the set is accessed.
4071 * @return the first element.
4072 * @throws NoSuchElementException if this set is empty.
4074 public T first()
4076 synchronized (mutex)
4078 return ss.first();
4083 * Returns a subset containing the element from the first
4084 * element (as returned by <code>first()</code>) to
4085 * the element before that specified. The subset supports all
4086 * operations supported by the underlying set and all actions
4087 * taking place on the subset are also reflected in the underlying
4088 * set. A lock is obtained on the mutex prior to subset creation.
4089 * This operation is equivalent to <code>subSet(first(), toElement)</code>.
4090 * The subset retains the thread-safe status of this set.
4092 * @param toElement the exclusive upper range of the subset.
4093 * @return a subset from <code>first()</code> to the
4094 * the element preceding toElement.
4095 * @throws ClassCastException if toElement is not comparable to the underlying
4096 * set's contents.
4097 * @throws IllegalArgumentException if toElement is outside the set's range.
4098 * @throws NullPointerException if toElement is null. but the set does not allow
4099 * null elements.
4101 public SortedSet<T> headSet(T toElement)
4103 synchronized (mutex)
4105 return new SynchronizedSortedSet<T>(mutex, ss.headSet(toElement));
4110 * Returns the last, highest sorted, element from the underlying set.
4111 * A lock is obtained on the mutex before the set is accessed.
4113 * @return the last element.
4114 * @throws NoSuchElementException if this set is empty.
4116 public T last()
4118 synchronized (mutex)
4120 return ss.last();
4125 * Returns a subset containing the elements from fromElement to
4126 * the element before toElement. The subset supports all
4127 * operations supported by the underlying set and all actions
4128 * taking place on the subset are also reflected in the underlying
4129 * set. A lock is obtained on the mutex prior to subset creation.
4130 * The subset retains the thread-safe status of this set.
4132 * @param fromElement the inclusive lower range of the subset.
4133 * @param toElement the exclusive upper range of the subset.
4134 * @return a subset from fromElement to the element preceding toElement.
4135 * @throws ClassCastException if fromElement or toElement is not comparable
4136 * to the underlying set's contents.
4137 * @throws IllegalArgumentException if fromElement or toElement is outside the set's
4138 * range.
4139 * @throws NullPointerException if fromElement or toElement is null. but the set does
4140 * not allow null elements.
4142 public SortedSet<T> subSet(T fromElement, T toElement)
4144 synchronized (mutex)
4146 return new SynchronizedSortedSet<T>(mutex,
4147 ss.subSet(fromElement,
4148 toElement));
4153 * Returns a subset containing all the elements from fromElement onwards.
4154 * The subset supports all operations supported by the underlying
4155 * set and all actions taking place on the subset are also reflected
4156 * in the underlying set. A lock is obtained on the mutex prior to
4157 * subset creation. The subset retains the thread-safe status of
4158 * this set.
4160 * @param fromElement the inclusive lower range of the subset.
4161 * @return a subset from fromElement to <code>last()</code>.
4162 * @throws ClassCastException if fromElement is not comparable to the underlying
4163 * set's contents.
4164 * @throws IllegalArgumentException if fromElement is outside the set's range.
4165 * @throws NullPointerException if fromElement is null. but the set does not allow
4166 * null elements.
4168 public SortedSet<T> tailSet(T fromElement)
4170 synchronized (mutex)
4172 return new SynchronizedSortedSet<T>(mutex, ss.tailSet(fromElement));
4175 } // class SynchronizedSortedSet
4179 * Returns an unmodifiable view of the given collection. This allows
4180 * "read-only" access, although changes in the backing collection show up
4181 * in this view. Attempts to modify the collection directly or via iterators
4182 * will fail with {@link UnsupportedOperationException}. Although this view
4183 * prevents changes to the structure of the collection and its elements, the values
4184 * referenced by the objects in the collection can still be modified.
4185 * <p>
4187 * Since the collection might be a List or a Set, and those have incompatible
4188 * equals and hashCode requirements, this relies on Object's implementation
4189 * rather than passing those calls on to the wrapped collection. The returned
4190 * Collection implements Serializable, but can only be serialized if
4191 * the collection it wraps is likewise Serializable.
4193 * @param c the collection to wrap
4194 * @return a read-only view of the collection
4195 * @see Serializable
4197 public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c)
4199 return new UnmodifiableCollection<T>(c);
4203 * The implementation of {@link #unmodifiableCollection(Collection)}. This
4204 * class name is required for compatibility with Sun's JDK serializability.
4206 * @author Eric Blake (ebb9@email.byu.edu)
4208 private static class UnmodifiableCollection<T>
4209 implements Collection<T>, Serializable
4212 * Compatible with JDK 1.4.
4214 private static final long serialVersionUID = 1820017752578914078L;
4217 * The wrapped collection. Package visible for use by subclasses.
4218 * @serial the real collection
4220 final Collection<? extends T> c;
4223 * Wrap a given collection.
4224 * @param c the collection to wrap
4225 * @throws NullPointerException if c is null
4227 UnmodifiableCollection(Collection<? extends T> c)
4229 this.c = c;
4230 if (c == null)
4231 throw new NullPointerException();
4235 * Blocks the addition of elements to the underlying collection.
4236 * This method never returns, throwing an exception instead.
4238 * @param o the object to add.
4239 * @return <code>true</code> if the collection was modified as a result of this action.
4240 * @throws UnsupportedOperationException as an unmodifiable collection does not
4241 * support the add operation.
4243 public boolean add(T o)
4245 throw new UnsupportedOperationException();
4249 * Blocks the addition of a collection of elements to the underlying
4250 * collection. This method never returns, throwing an exception instead.
4252 * @param c the collection to add.
4253 * @return <code>true</code> if the collection was modified as a result of this action.
4254 * @throws UnsupportedOperationException as an unmodifiable collection does not
4255 * support the <code>addAll</code> operation.
4257 public boolean addAll(Collection<? extends T> c)
4259 throw new UnsupportedOperationException();
4263 * Blocks the clearing of the underlying collection. This method never
4264 * returns, throwing an exception instead.
4266 * @throws UnsupportedOperationException as an unmodifiable collection does
4267 * not support the <code>clear()</code> operation.
4269 public void clear()
4271 throw new UnsupportedOperationException();
4275 * Test whether the underlying collection contains a given object as one of its
4276 * elements.
4278 * @param o the element to look for.
4279 * @return <code>true</code> if the underlying collection contains at least
4280 * one element e such that
4281 * <code>o == null ? e == null : o.equals(e)</code>.
4282 * @throws ClassCastException if the type of o is not a valid type for the
4283 * underlying collection.
4284 * @throws NullPointerException if o is null and the underlying collection
4285 * doesn't support null values.
4287 public boolean contains(Object o)
4289 return c.contains(o);
4293 * Test whether the underlying collection contains every element in a given
4294 * collection.
4296 * @param c1 the collection to test for.
4297 * @return <code>true</code> if for every element o in c, contains(o) would
4298 * return <code>true</code>.
4299 * @throws ClassCastException if the type of any element in c is not a valid
4300 * type for the underlying collection.
4301 * @throws NullPointerException if some element of c is null and the underlying
4302 * collection does not support null values.
4303 * @throws NullPointerException if c itself is null.
4305 public boolean containsAll(Collection<?> c1)
4307 return c.containsAll(c1);
4311 * Tests whether the underlying collection is empty, that is,
4312 * if size() == 0.
4314 * @return <code>true</code> if this collection contains no elements.
4316 public boolean isEmpty()
4318 return c.isEmpty();
4322 * Obtain an Iterator over the underlying collection, which maintains
4323 * its unmodifiable nature.
4325 * @return an UnmodifiableIterator over the elements of the underlying
4326 * collection, in any order.
4328 public Iterator<T> iterator()
4330 return new UnmodifiableIterator<T>(c.iterator());
4334 * Blocks the removal of an object from the underlying collection.
4335 * This method never returns, throwing an exception instead.
4337 * @param o The object to remove.
4338 * @return <code>true</code> if the object was removed (i.e. the underlying
4339 * collection returned 1 or more instances of o).
4340 * @throws UnsupportedOperationException as an unmodifiable collection
4341 * does not support the <code>remove()</code> operation.
4343 public boolean remove(Object o)
4345 throw new UnsupportedOperationException();
4349 * Blocks the removal of a collection of objects from the underlying
4350 * collection. This method never returns, throwing an exception
4351 * instead.
4353 * @param c The collection of objects to remove.
4354 * @return <code>true</code> if the collection was modified.
4355 * @throws UnsupportedOperationException as an unmodifiable collection
4356 * does not support the <code>removeAll()</code> operation.
4358 public boolean removeAll(Collection<?> c)
4360 throw new UnsupportedOperationException();
4364 * Blocks the removal of all elements from the underlying collection,
4365 * except those in the supplied collection. This method never returns,
4366 * throwing an exception instead.
4368 * @param c The collection of objects to retain.
4369 * @return <code>true</code> if the collection was modified.
4370 * @throws UnsupportedOperationException as an unmodifiable collection
4371 * does not support the <code>retainAll()</code> operation.
4373 public boolean retainAll(Collection<?> c)
4375 throw new UnsupportedOperationException();
4379 * Retrieves the number of elements in the underlying collection.
4381 * @return the number of elements in the collection.
4383 public int size()
4385 return c.size();
4389 * Copy the current contents of the underlying collection into an array.
4391 * @return an array of type Object[] with a length equal to the size of the
4392 * underlying collection and containing the elements currently in
4393 * the underlying collection, in any order.
4395 public Object[] toArray()
4397 return c.toArray();
4401 * Copy the current contents of the underlying collection into an array. If
4402 * the array passed as an argument has length less than the size of the
4403 * underlying collection, an array of the same run-time type as a, with a length
4404 * equal to the size of the underlying collection, is allocated using reflection.
4405 * Otherwise, a itself is used. The elements of the underlying collection are
4406 * copied into it, and if there is space in the array, the following element is
4407 * set to null. The resultant array is returned.
4408 * Note: The fact that the following element is set to null is only useful
4409 * if it is known that this collection does not contain any null elements.
4411 * @param a the array to copy this collection into.
4412 * @return an array containing the elements currently in the underlying
4413 * collection, in any order.
4414 * @throws ArrayStoreException if the type of any element of the
4415 * collection is not a subtype of the element type of a.
4417 public <S> S[] toArray(S[] a)
4419 return c.toArray(a);
4423 * A textual representation of the unmodifiable collection.
4425 * @return The unmodifiable collection in the form of a <code>String</code>.
4427 public String toString()
4429 return c.toString();
4431 } // class UnmodifiableCollection
4434 * The implementation of the various iterator methods in the
4435 * unmodifiable classes.
4437 * @author Eric Blake (ebb9@email.byu.edu)
4439 private static class UnmodifiableIterator<T> implements Iterator<T>
4442 * The wrapped iterator.
4444 private final Iterator<? extends T> i;
4447 * Only trusted code creates a wrapper.
4448 * @param i the wrapped iterator
4450 UnmodifiableIterator(Iterator<? extends T> i)
4452 this.i = i;
4456 * Obtains the next element in the underlying collection.
4458 * @return the next element in the collection.
4459 * @throws NoSuchElementException if there are no more elements.
4461 public T next()
4463 return i.next();
4467 * Tests whether there are still elements to be retrieved from the
4468 * underlying collection by <code>next()</code>. When this method
4469 * returns <code>true</code>, an exception will not be thrown on calling
4470 * <code>next()</code>.
4472 * @return <code>true</code> if there is at least one more element in the underlying
4473 * collection.
4475 public boolean hasNext()
4477 return i.hasNext();
4481 * Blocks the removal of elements from the underlying collection by the
4482 * iterator.
4484 * @throws UnsupportedOperationException as an unmodifiable collection
4485 * does not support the removal of elements by its iterator.
4487 public void remove()
4489 throw new UnsupportedOperationException();
4491 } // class UnmodifiableIterator
4494 * Returns an unmodifiable view of the given list. This allows
4495 * "read-only" access, although changes in the backing list show up
4496 * in this view. Attempts to modify the list directly, via iterators, or
4497 * via sublists, will fail with {@link UnsupportedOperationException}.
4498 * Although this view prevents changes to the structure of the list and
4499 * its elements, the values referenced by the objects in the list can
4500 * still be modified.
4501 * <p>
4503 * The returned List implements Serializable, but can only be serialized if
4504 * the list it wraps is likewise Serializable. In addition, if the wrapped
4505 * list implements RandomAccess, this does too.
4507 * @param l the list to wrap
4508 * @return a read-only view of the list
4509 * @see Serializable
4510 * @see RandomAccess
4512 public static <T> List<T> unmodifiableList(List<? extends T> l)
4514 if (l instanceof RandomAccess)
4515 return new UnmodifiableRandomAccessList<T>(l);
4516 return new UnmodifiableList<T>(l);
4520 * The implementation of {@link #unmodifiableList(List)} for sequential
4521 * lists. This class name is required for compatibility with Sun's JDK
4522 * serializability.
4524 * @author Eric Blake (ebb9@email.byu.edu)
4526 private static class UnmodifiableList<T> extends UnmodifiableCollection<T>
4527 implements List<T>
4530 * Compatible with JDK 1.4.
4532 private static final long serialVersionUID = -283967356065247728L;
4536 * The wrapped list; stored both here and in the superclass to avoid
4537 * excessive casting. Package visible for use by subclass.
4538 * @serial the wrapped list
4540 final List<T> list;
4543 * Wrap a given list.
4544 * @param l the list to wrap
4545 * @throws NullPointerException if l is null
4547 UnmodifiableList(List<? extends T> l)
4549 super(l);
4550 list = (List<T>) l;
4554 * Blocks the addition of an element to the underlying
4555 * list at a specific index. This method never returns,
4556 * throwing an exception instead.
4558 * @param index The index at which to place the new element.
4559 * @param o the object to add.
4560 * @throws UnsupportedOperationException as an unmodifiable
4561 * list doesn't support the <code>add()</code> operation.
4563 public void add(int index, T o)
4565 throw new UnsupportedOperationException();
4569 * Blocks the addition of a collection of elements to the
4570 * underlying list at a specific index. This method never
4571 * returns, throwing an exception instead.
4573 * @param index The index at which to place the new element.
4574 * @param c the collections of objects to add.
4575 * @throws UnsupportedOperationException as an unmodifiable
4576 * list doesn't support the <code>addAll()</code> operation.
4578 public boolean addAll(int index, Collection<? extends T> c)
4580 throw new UnsupportedOperationException();
4584 * Returns <code>true</code> if the object, o, is an instance of
4585 * <code>List</code> with the same size and elements
4586 * as the underlying list.
4588 * @param o The object to compare.
4589 * @return <code>true</code> if o is equivalent to the underlying list.
4591 public boolean equals(Object o)
4593 return list.equals(o);
4597 * Retrieves the element at a given index in the underlying list.
4599 * @param index the index of the element to be returned
4600 * @return the element at index index in this list
4601 * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
4603 public T get(int index)
4605 return list.get(index);
4609 * Computes the hash code for the underlying list.
4610 * The exact computation is described in the documentation
4611 * of the <code>List</code> interface.
4613 * @return The hash code of the underlying list.
4614 * @see List#hashCode()
4616 public int hashCode()
4618 return list.hashCode();
4622 * Obtain the first index at which a given object is to be found in the
4623 * underlying list.
4625 * @param o the object to search for
4626 * @return the least integer n such that <code>o == null ? get(n) == null :
4627 * o.equals(get(n))</code>, or -1 if there is no such index.
4628 * @throws ClassCastException if the type of o is not a valid
4629 * type for the underlying list.
4630 * @throws NullPointerException if o is null and the underlying
4631 * list does not support null values.
4633 public int indexOf(Object o)
4635 return list.indexOf(o);
4639 * Obtain the last index at which a given object is to be found in the
4640 * underlying list.
4642 * @return the greatest integer n such that <code>o == null ? get(n) == null
4643 * : o.equals(get(n))</code>, or -1 if there is no such index.
4644 * @throws ClassCastException if the type of o is not a valid
4645 * type for the underlying list.
4646 * @throws NullPointerException if o is null and the underlying
4647 * list does not support null values.
4649 public int lastIndexOf(Object o)
4651 return list.lastIndexOf(o);
4655 * Obtains a list iterator over the underlying list, starting at the beginning
4656 * and maintaining the unmodifiable nature of this list.
4658 * @return a <code>UnmodifiableListIterator</code> over the elements of the
4659 * underlying list, in order, starting at the beginning.
4661 public ListIterator<T> listIterator()
4663 return new UnmodifiableListIterator<T>(list.listIterator());
4667 * Obtains a list iterator over the underlying list, starting at the specified
4668 * index and maintaining the unmodifiable nature of this list. An initial call
4669 * to <code>next()</code> will retrieve the element at the specified index,
4670 * and an initial call to <code>previous()</code> will retrieve the element
4671 * at index - 1.
4674 * @param index the position, between 0 and size() inclusive, to begin the
4675 * iteration from.
4676 * @return a <code>UnmodifiableListIterator</code> over the elements of the
4677 * underlying list, in order, starting at the specified index.
4678 * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
4680 public ListIterator<T> listIterator(int index)
4682 return new UnmodifiableListIterator<T>(list.listIterator(index));
4686 * Blocks the removal of the element at the specified index.
4687 * This method never returns, throwing an exception instead.
4689 * @param index The index of the element to remove.
4690 * @return the removed element.
4691 * @throws UnsupportedOperationException as an unmodifiable
4692 * list does not support the <code>remove()</code>
4693 * operation.
4695 public T remove(int index)
4697 throw new UnsupportedOperationException();
4701 * Blocks the replacement of the element at the specified index.
4702 * This method never returns, throwing an exception instead.
4704 * @param index The index of the element to replace.
4705 * @param o The new object to place at the specified index.
4706 * @return the replaced element.
4707 * @throws UnsupportedOperationException as an unmodifiable
4708 * list does not support the <code>set()</code>
4709 * operation.
4711 public T set(int index, T o)
4713 throw new UnsupportedOperationException();
4717 * Obtain a List view of a subsection of the underlying list, from
4718 * fromIndex (inclusive) to toIndex (exclusive). If the two indices
4719 * are equal, the sublist is empty. The returned list will be
4720 * unmodifiable, like this list. Changes to the elements of the
4721 * returned list will be reflected in the underlying list. No structural
4722 * modifications can take place in either list.
4724 * @param fromIndex the index that the returned list should start from
4725 * (inclusive).
4726 * @param toIndex the index that the returned list should go to (exclusive).
4727 * @return a List backed by a subsection of the underlying list.
4728 * @throws IndexOutOfBoundsException if fromIndex &lt; 0
4729 * || toIndex &gt; size() || fromIndex &gt; toIndex.
4731 public List<T> subList(int fromIndex, int toIndex)
4733 return unmodifiableList(list.subList(fromIndex, toIndex));
4735 } // class UnmodifiableList
4738 * The implementation of {@link #unmodifiableList(List)} for random-access
4739 * lists. This class name is required for compatibility with Sun's JDK
4740 * serializability.
4742 * @author Eric Blake (ebb9@email.byu.edu)
4744 private static final class UnmodifiableRandomAccessList<T>
4745 extends UnmodifiableList<T> implements RandomAccess
4748 * Compatible with JDK 1.4.
4750 private static final long serialVersionUID = -2542308836966382001L;
4753 * Wrap a given list.
4754 * @param l the list to wrap
4755 * @throws NullPointerException if l is null
4757 UnmodifiableRandomAccessList(List<? extends T> l)
4759 super(l);
4761 } // class UnmodifiableRandomAccessList
4764 * The implementation of {@link UnmodifiableList#listIterator()}.
4766 * @author Eric Blake (ebb9@email.byu.edu)
4768 private static final class UnmodifiableListIterator<T>
4769 extends UnmodifiableIterator<T> implements ListIterator<T>
4772 * The wrapped iterator, stored both here and in the superclass to
4773 * avoid excessive casting.
4775 private final ListIterator<T> li;
4778 * Only trusted code creates a wrapper.
4779 * @param li the wrapped iterator
4781 UnmodifiableListIterator(ListIterator<T> li)
4783 super(li);
4784 this.li = li;
4788 * Blocks the addition of an object to the list underlying this iterator.
4789 * This method never returns, throwing an exception instead.
4791 * @param o The object to add.
4792 * @throws UnsupportedOperationException as the iterator of an unmodifiable
4793 * list does not support the <code>add()</code> operation.
4795 public void add(T o)
4797 throw new UnsupportedOperationException();
4801 * Tests whether there are still elements to be retrieved from the
4802 * underlying collection by <code>previous()</code>. When this method
4803 * returns <code>true</code>, an exception will not be thrown on calling
4804 * <code>previous()</code>.
4806 * @return <code>true</code> if there is at least one more element prior to the
4807 * current position in the underlying list.
4809 public boolean hasPrevious()
4811 return li.hasPrevious();
4815 * Find the index of the element that would be returned by a call to next.
4816 * If <code>hasNext()</code> returns <code>false</code>, this returns the list size.
4818 * @return the index of the element that would be returned by
4819 * <code>next()</code>.
4821 public int nextIndex()
4823 return li.nextIndex();
4827 * Obtains the previous element in the underlying list.
4829 * @return the previous element in the list.
4830 * @throws NoSuchElementException if there are no more prior elements.
4832 public T previous()
4834 return li.previous();
4838 * Find the index of the element that would be returned by a call to
4839 * previous. If <code>hasPrevious()</code> returns <code>false</code>,
4840 * this returns -1.
4842 * @return the index of the element that would be returned by
4843 * <code>previous()</code>.
4845 public int previousIndex()
4847 return li.previousIndex();
4851 * Blocks the replacement of an element in the list underlying this
4852 * iterator. This method never returns, throwing an exception instead.
4854 * @param o The new object to replace the existing one.
4855 * @throws UnsupportedOperationException as the iterator of an unmodifiable
4856 * list does not support the <code>set()</code> operation.
4858 public void set(T o)
4860 throw new UnsupportedOperationException();
4862 } // class UnmodifiableListIterator
4865 * Returns an unmodifiable view of the given map. This allows "read-only"
4866 * access, although changes in the backing map show up in this view.
4867 * Attempts to modify the map directly, or via collection views or their
4868 * iterators will fail with {@link UnsupportedOperationException}.
4869 * Although this view prevents changes to the structure of the map and its
4870 * entries, the values referenced by the objects in the map can still be
4871 * modified.
4872 * <p>
4874 * The returned Map implements Serializable, but can only be serialized if
4875 * the map it wraps is likewise Serializable.
4877 * @param m the map to wrap
4878 * @return a read-only view of the map
4879 * @see Serializable
4881 public static <K, V> Map<K, V> unmodifiableMap(Map<? extends K,
4882 ? extends V> m)
4884 return new UnmodifiableMap<K, V>(m);
4888 * The implementation of {@link #unmodifiableMap(Map)}. This
4889 * class name is required for compatibility with Sun's JDK serializability.
4891 * @author Eric Blake (ebb9@email.byu.edu)
4893 private static class UnmodifiableMap<K, V> implements Map<K, V>, Serializable
4896 * Compatible with JDK 1.4.
4898 private static final long serialVersionUID = -1034234728574286014L;
4901 * The wrapped map.
4902 * @serial the real map
4904 private final Map<K, V> m;
4907 * Cache the entry set.
4909 private transient Set<Map.Entry<K, V>> entries;
4912 * Cache the key set.
4914 private transient Set<K> keys;
4917 * Cache the value collection.
4919 private transient Collection<V> values;
4922 * Wrap a given map.
4923 * @param m the map to wrap
4924 * @throws NullPointerException if m is null
4926 UnmodifiableMap(Map<? extends K, ? extends V> m)
4928 this.m = (Map<K,V>) m;
4929 if (m == null)
4930 throw new NullPointerException();
4934 * Blocks the clearing of entries from the underlying map.
4935 * This method never returns, throwing an exception instead.
4937 * @throws UnsupportedOperationException as an unmodifiable
4938 * map does not support the <code>clear()</code> operation.
4940 public void clear()
4942 throw new UnsupportedOperationException();
4946 * Returns <code>true</code> if the underlying map contains a mapping for
4947 * the given key.
4949 * @param key the key to search for
4950 * @return <code>true</code> if the map contains the key
4951 * @throws ClassCastException if the key is of an inappropriate type
4952 * @throws NullPointerException if key is <code>null</code> but the map
4953 * does not permit null keys
4955 public boolean containsKey(Object key)
4957 return m.containsKey(key);
4961 * Returns <code>true</code> if the underlying map contains at least one mapping with
4962 * the given value. In other words, it returns <code>true</code> if a value v exists where
4963 * <code>(value == null ? v == null : value.equals(v))</code>. This usually
4964 * requires linear time.
4966 * @param value the value to search for
4967 * @return <code>true</code> if the map contains the value
4968 * @throws ClassCastException if the type of the value is not a valid type
4969 * for this map.
4970 * @throws NullPointerException if the value is null and the map doesn't
4971 * support null values.
4973 public boolean containsValue(Object value)
4975 return m.containsValue(value);
4979 * Returns a unmodifiable set view of the entries in the underlying map.
4980 * Each element in the set is a unmodifiable variant of <code>Map.Entry</code>.
4981 * The set is backed by the map, so that changes in one show up in the other.
4982 * Modifications made while an iterator is in progress cause undefined
4983 * behavior. These modifications are again limited to the values of
4984 * the objects.
4986 * @return the unmodifiable set view of all mapping entries.
4987 * @see Map.Entry
4989 public Set<Map.Entry<K, V>> entrySet()
4991 if (entries == null)
4992 entries = new UnmodifiableEntrySet<K,V>(m.entrySet());
4993 return entries;
4997 * The implementation of {@link UnmodifiableMap#entrySet()}. This class
4998 * name is required for compatibility with Sun's JDK serializability.
5000 * @author Eric Blake (ebb9@email.byu.edu)
5002 private static final class UnmodifiableEntrySet<K,V>
5003 extends UnmodifiableSet<Map.Entry<K,V>>
5004 implements Serializable
5006 // Unmodifiable implementation of Map.Entry used as return value for
5007 // UnmodifiableEntrySet accessors (iterator, toArray, toArray(Object[]))
5008 private static final class UnmodifiableMapEntry<K,V>
5009 implements Map.Entry<K,V>
5011 private final Map.Entry<K,V> e;
5013 private UnmodifiableMapEntry(Map.Entry<K,V> e)
5015 super();
5016 this.e = e;
5020 * Returns <code>true</code> if the object, o, is also a map entry
5021 * with an identical key and value.
5023 * @param o the object to compare.
5024 * @return <code>true</code> if o is an equivalent map entry.
5026 public boolean equals(Object o)
5028 return e.equals(o);
5032 * Returns the key of this map entry.
5034 * @return the key.
5036 public K getKey()
5038 return e.getKey();
5042 * Returns the value of this map entry.
5044 * @return the value.
5046 public V getValue()
5048 return e.getValue();
5052 * Computes the hash code of this map entry. The computation is
5053 * described in the <code>Map</code> interface documentation.
5055 * @return the hash code of this entry.
5056 * @see Map#hashCode()
5058 public int hashCode()
5060 return e.hashCode();
5064 * Blocks the alteration of the value of this map entry. This method
5065 * never returns, throwing an exception instead.
5067 * @param value The new value.
5068 * @throws UnsupportedOperationException as an unmodifiable map entry
5069 * does not support the <code>setValue()</code> operation.
5071 public V setValue(V value)
5073 throw new UnsupportedOperationException();
5077 * Returns a textual representation of the map entry.
5079 * @return The map entry as a <code>String</code>.
5081 public String toString()
5083 return e.toString();
5088 * Compatible with JDK 1.4.
5090 private static final long serialVersionUID = 7854390611657943733L;
5093 * Wrap a given set.
5094 * @param s the set to wrap
5096 UnmodifiableEntrySet(Set<Map.Entry<K,V>> s)
5098 super(s);
5101 // The iterator must return unmodifiable map entries.
5102 public Iterator<Map.Entry<K,V>> iterator()
5104 return new UnmodifiableIterator<Map.Entry<K,V>>(c.iterator())
5107 * Obtains the next element from the underlying set of
5108 * map entries.
5110 * @return the next element in the collection.
5111 * @throws NoSuchElementException if there are no more elements.
5113 public Map.Entry<K,V> next()
5115 final Map.Entry<K,V> e = super.next();
5116 return new UnmodifiableMapEntry<K,V>(e);
5121 // The array returned is an array of UnmodifiableMapEntry instead of
5122 // Map.Entry
5123 public Object[] toArray()
5125 Object[] mapEntryResult = super.toArray();
5126 UnmodifiableMapEntry<K,V> result[] = null;
5128 if (mapEntryResult != null)
5130 result = (UnmodifiableMapEntry<K,V>[])
5131 new UnmodifiableMapEntry[mapEntryResult.length];
5132 for (int i = 0; i < mapEntryResult.length; ++i)
5133 result[i] = new UnmodifiableMapEntry<K,V>((Map.Entry<K,V>)mapEntryResult[i]);
5135 return result;
5138 // The array returned is an array of UnmodifiableMapEntry instead of
5139 // Map.Entry
5140 public <S> S[] toArray(S[] array)
5142 S[] result = super.toArray(array);
5144 if (result != null)
5145 for (int i = 0; i < result.length; i++)
5146 array[i] =
5147 (S) new UnmodifiableMapEntry<K,V>((Map.Entry<K,V>) result[i]);
5148 return array;
5152 } // class UnmodifiableEntrySet
5155 * Returns <code>true</code> if the object, o, is also an instance
5156 * of <code>Map</code> with an equal set of map entries.
5158 * @param o The object to compare.
5159 * @return <code>true</code> if o is an equivalent map.
5161 public boolean equals(Object o)
5163 return m.equals(o);
5167 * Returns the value associated with the supplied key or
5168 * null if no such mapping exists. An ambiguity can occur
5169 * if null values are accepted by the underlying map.
5170 * In this case, <code>containsKey()</code> can be used
5171 * to separate the two possible cases of a null result.
5173 * @param key The key to look up.
5174 * @return the value associated with the key, or null if key not in map.
5175 * @throws ClassCastException if the key is an inappropriate type.
5176 * @throws NullPointerException if this map does not accept null keys.
5177 * @see #containsKey(Object)
5179 public V get(Object key)
5181 return m.get(key);
5185 * Blocks the addition of a new entry to the underlying map.
5186 * This method never returns, throwing an exception instead.
5188 * @param key The new key.
5189 * @param value The new value.
5190 * @return the previous value of the key, or null if there was no mapping.
5191 * @throws UnsupportedOperationException as an unmodifiable
5192 * map does not support the <code>put()</code> operation.
5194 public V put(K key, V value)
5196 throw new UnsupportedOperationException();
5200 * Computes the hash code for the underlying map, as the sum
5201 * of the hash codes of all entries.
5203 * @return The hash code of the underlying map.
5204 * @see Map.Entry#hashCode()
5206 public int hashCode()
5208 return m.hashCode();
5212 * Returns <code>true</code> if the underlying map contains no entries.
5214 * @return <code>true</code> if the map is empty.
5216 public boolean isEmpty()
5218 return m.isEmpty();
5222 * Returns a unmodifiable set view of the keys in the underlying map.
5223 * The set is backed by the map, so that changes in one show up in the other.
5224 * Modifications made while an iterator is in progress cause undefined
5225 * behavior. These modifications are again limited to the values of
5226 * the keys.
5228 * @return the set view of all keys.
5230 public Set<K> keySet()
5232 if (keys == null)
5233 keys = new UnmodifiableSet<K>(m.keySet());
5234 return keys;
5238 * Blocks the addition of the entries in the supplied map.
5239 * This method never returns, throwing an exception instead.
5241 * @param m The map, the entries of which should be added
5242 * to the underlying map.
5243 * @throws UnsupportedOperationException as an unmodifiable
5244 * map does not support the <code>putAll</code> operation.
5246 public void putAll(Map<? extends K, ? extends V> m)
5248 throw new UnsupportedOperationException();
5252 * Blocks the removal of an entry from the map.
5253 * This method never returns, throwing an exception instead.
5255 * @param o The key of the entry to remove.
5256 * @return The value the key was associated with, or null
5257 * if no such mapping existed. Null is also returned
5258 * if the removed entry had a null key.
5259 * @throws UnsupportedOperationException as an unmodifiable
5260 * map does not support the <code>remove</code> operation.
5262 public V remove(Object o)
5264 throw new UnsupportedOperationException();
5269 * Returns the number of key-value mappings in the underlying map.
5270 * If there are more than Integer.MAX_VALUE mappings, Integer.MAX_VALUE
5271 * is returned.
5273 * @return the number of mappings.
5275 public int size()
5277 return m.size();
5281 * Returns a textual representation of the map.
5283 * @return The map in the form of a <code>String</code>.
5285 public String toString()
5287 return m.toString();
5291 * Returns a unmodifiable collection view of the values in the underlying map.
5292 * The collection is backed by the map, so that changes in one show up in the other.
5293 * Modifications made while an iterator is in progress cause undefined
5294 * behavior. These modifications are again limited to the values of
5295 * the keys.
5297 * @return the collection view of all values.
5299 public Collection<V> values()
5301 if (values == null)
5302 values = new UnmodifiableCollection<V>(m.values());
5303 return values;
5305 } // class UnmodifiableMap
5308 * Returns an unmodifiable view of the given set. This allows
5309 * "read-only" access, although changes in the backing set show up
5310 * in this view. Attempts to modify the set directly or via iterators
5311 * will fail with {@link UnsupportedOperationException}.
5312 * Although this view prevents changes to the structure of the set and its
5313 * entries, the values referenced by the objects in the set can still be
5314 * modified.
5315 * <p>
5317 * The returned Set implements Serializable, but can only be serialized if
5318 * the set it wraps is likewise Serializable.
5320 * @param s the set to wrap
5321 * @return a read-only view of the set
5322 * @see Serializable
5324 public static <T> Set<T> unmodifiableSet(Set<? extends T> s)
5326 return new UnmodifiableSet<T>(s);
5330 * The implementation of {@link #unmodifiableSet(Set)}. This class
5331 * name is required for compatibility with Sun's JDK serializability.
5333 * @author Eric Blake (ebb9@email.byu.edu)
5335 private static class UnmodifiableSet<T> extends UnmodifiableCollection<T>
5336 implements Set<T>
5339 * Compatible with JDK 1.4.
5341 private static final long serialVersionUID = -9215047833775013803L;
5344 * Wrap a given set.
5345 * @param s the set to wrap
5346 * @throws NullPointerException if s is null
5348 UnmodifiableSet(Set<? extends T> s)
5350 super(s);
5354 * Returns <code>true</code> if the object, o, is also an instance of
5355 * <code>Set</code> of the same size and with the same entries.
5357 * @return <code>true</code> if o is an equivalent set.
5359 public boolean equals(Object o)
5361 return c.equals(o);
5365 * Computes the hash code of this set, as the sum of the
5366 * hash codes of all elements within the set.
5368 * @return the hash code of the set.
5370 public int hashCode()
5372 return c.hashCode();
5374 } // class UnmodifiableSet
5377 * Returns an unmodifiable view of the given sorted map. This allows
5378 * "read-only" access, although changes in the backing map show up in this
5379 * view. Attempts to modify the map directly, via subviews, via collection
5380 * views, or iterators, will fail with {@link UnsupportedOperationException}.
5381 * Although this view prevents changes to the structure of the map and its
5382 * entries, the values referenced by the objects in the map can still be
5383 * modified.
5384 * <p>
5386 * The returned SortedMap implements Serializable, but can only be
5387 * serialized if the map it wraps is likewise Serializable.
5389 * @param m the map to wrap
5390 * @return a read-only view of the map
5391 * @see Serializable
5393 public static <K, V> SortedMap<K, V> unmodifiableSortedMap(SortedMap<K,
5394 ? extends V> m)
5396 return new UnmodifiableSortedMap<K, V>(m);
5400 * The implementation of {@link #unmodifiableSortedMap(SortedMap)}. This
5401 * class name is required for compatibility with Sun's JDK serializability.
5403 * @author Eric Blake (ebb9@email.byu.edu)
5405 private static class UnmodifiableSortedMap<K, V>
5406 extends UnmodifiableMap<K, V>
5407 implements SortedMap<K, V>
5410 * Compatible with JDK 1.4.
5412 private static final long serialVersionUID = -8806743815996713206L;
5415 * The wrapped map; stored both here and in the superclass to avoid
5416 * excessive casting.
5417 * @serial the wrapped map
5419 private final SortedMap<K, V> sm;
5422 * Wrap a given map.
5423 * @param sm the map to wrap
5424 * @throws NullPointerException if sm is null
5426 UnmodifiableSortedMap(SortedMap<K, ? extends V> sm)
5428 super(sm);
5429 this.sm = (SortedMap<K,V>) sm;
5433 * Returns the comparator used in sorting the underlying map,
5434 * or null if it is the keys' natural ordering.
5436 * @return the sorting comparator.
5438 public Comparator<? super K> comparator()
5440 return sm.comparator();
5444 * Returns the first (lowest sorted) key in the map.
5446 * @return the first key.
5447 * @throws NoSuchElementException if this map is empty.
5449 public K firstKey()
5451 return sm.firstKey();
5455 * Returns a unmodifiable view of the portion of the map strictly less
5456 * than toKey. The view is backed by the underlying map, so changes in
5457 * one show up in the other. The submap supports all optional operations
5458 * of the original. This operation is equivalent to
5459 * <code>subMap(firstKey(), toKey)</code>.
5460 * <p>
5462 * The returned map throws an IllegalArgumentException any time a key is
5463 * used which is out of the range of toKey. Note that the endpoint, toKey,
5464 * is not included; if you want this value to be included, pass its successor
5465 * object in to toKey. For example, for Integers, you could request
5466 * <code>headMap(new Integer(limit.intValue() + 1))</code>.
5468 * @param toKey the exclusive upper range of the submap.
5469 * @return the submap.
5470 * @throws ClassCastException if toKey is not comparable to the map contents.
5471 * @throws IllegalArgumentException if this is a subMap, and toKey is out
5472 * of range.
5473 * @throws NullPointerException if toKey is null but the map does not allow
5474 * null keys.
5476 public SortedMap<K, V> headMap(K toKey)
5478 return new UnmodifiableSortedMap<K, V>(sm.headMap(toKey));
5482 * Returns the last (highest sorted) key in the map.
5484 * @return the last key.
5485 * @throws NoSuchElementException if this map is empty.
5487 public K lastKey()
5489 return sm.lastKey();
5493 * Returns a unmodifiable view of the portion of the map greater than or
5494 * equal to fromKey, and strictly less than toKey. The view is backed by
5495 * the underlying map, so changes in one show up in the other. The submap
5496 * supports all optional operations of the original.
5497 * <p>
5499 * The returned map throws an IllegalArgumentException any time a key is
5500 * used which is out of the range of fromKey and toKey. Note that the
5501 * lower endpoint is included, but the upper is not; if you want to
5502 * change the inclusion or exclusion of an endpoint, pass its successor
5503 * object in instead. For example, for Integers, you could request
5504 * <code>subMap(new Integer(lowlimit.intValue() + 1),
5505 * new Integer(highlimit.intValue() + 1))</code> to reverse
5506 * the inclusiveness of both endpoints.
5508 * @param fromKey the inclusive lower range of the submap.
5509 * @param toKey the exclusive upper range of the submap.
5510 * @return the submap.
5511 * @throws ClassCastException if fromKey or toKey is not comparable to
5512 * the map contents.
5513 * @throws IllegalArgumentException if this is a subMap, and fromKey or
5514 * toKey is out of range.
5515 * @throws NullPointerException if fromKey or toKey is null but the map
5516 * does not allow null keys.
5518 public SortedMap<K, V> subMap(K fromKey, K toKey)
5520 return new UnmodifiableSortedMap<K, V>(sm.subMap(fromKey, toKey));
5524 * Returns a unmodifiable view of the portion of the map greater than or
5525 * equal to fromKey. The view is backed by the underlying map, so changes
5526 * in one show up in the other. The submap supports all optional operations
5527 * of the original.
5528 * <p>
5530 * The returned map throws an IllegalArgumentException any time a key is
5531 * used which is out of the range of fromKey. Note that the endpoint, fromKey, is
5532 * included; if you do not want this value to be included, pass its successor object in
5533 * to fromKey. For example, for Integers, you could request
5534 * <code>tailMap(new Integer(limit.intValue() + 1))</code>.
5536 * @param fromKey the inclusive lower range of the submap
5537 * @return the submap
5538 * @throws ClassCastException if fromKey is not comparable to the map
5539 * contents
5540 * @throws IllegalArgumentException if this is a subMap, and fromKey is out
5541 * of range
5542 * @throws NullPointerException if fromKey is null but the map does not allow
5543 * null keys
5545 public SortedMap<K, V> tailMap(K fromKey)
5547 return new UnmodifiableSortedMap<K, V>(sm.tailMap(fromKey));
5549 } // class UnmodifiableSortedMap
5552 * Returns an unmodifiable view of the given sorted set. This allows
5553 * "read-only" access, although changes in the backing set show up
5554 * in this view. Attempts to modify the set directly, via subsets, or via
5555 * iterators, will fail with {@link UnsupportedOperationException}.
5556 * Although this view prevents changes to the structure of the set and its
5557 * entries, the values referenced by the objects in the set can still be
5558 * modified.
5559 * <p>
5561 * The returns SortedSet implements Serializable, but can only be
5562 * serialized if the set it wraps is likewise Serializable.
5564 * @param s the set to wrap
5565 * @return a read-only view of the set
5566 * @see Serializable
5568 public static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s)
5570 return new UnmodifiableSortedSet<T>(s);
5574 * The implementation of {@link #synchronizedSortedMap(SortedMap)}. This
5575 * class name is required for compatibility with Sun's JDK serializability.
5577 * @author Eric Blake (ebb9@email.byu.edu)
5579 private static class UnmodifiableSortedSet<T> extends UnmodifiableSet<T>
5580 implements SortedSet<T>
5583 * Compatible with JDK 1.4.
5585 private static final long serialVersionUID = -4929149591599911165L;
5588 * The wrapped set; stored both here and in the superclass to avoid
5589 * excessive casting.
5590 * @serial the wrapped set
5592 private SortedSet<T> ss;
5595 * Wrap a given set.
5596 * @param ss the set to wrap
5597 * @throws NullPointerException if ss is null
5599 UnmodifiableSortedSet(SortedSet<T> ss)
5601 super(ss);
5602 this.ss = ss;
5606 * Returns the comparator used in sorting the underlying set,
5607 * or null if it is the elements' natural ordering.
5609 * @return the sorting comparator
5611 public Comparator<? super T> comparator()
5613 return ss.comparator();
5617 * Returns the first (lowest sorted) element in the underlying
5618 * set.
5620 * @return the first element.
5621 * @throws NoSuchElementException if the set is empty.
5623 public T first()
5625 return ss.first();
5629 * Returns a unmodifiable view of the portion of the set strictly
5630 * less than toElement. The view is backed by the underlying set,
5631 * so changes in one show up in the other. The subset supports
5632 * all optional operations of the original. This operation
5633 * is equivalent to <code>subSet(first(), toElement)</code>.
5634 * <p>
5636 * The returned set throws an IllegalArgumentException any time an element is
5637 * used which is out of the range of toElement. Note that the endpoint, toElement,
5638 * is not included; if you want this value included, pass its successor object in to
5639 * toElement. For example, for Integers, you could request
5640 * <code>headSet(new Integer(limit.intValue() + 1))</code>.
5642 * @param toElement the exclusive upper range of the subset
5643 * @return the subset.
5644 * @throws ClassCastException if toElement is not comparable to the set
5645 * contents.
5646 * @throws IllegalArgumentException if this is a subSet, and toElement is out
5647 * of range.
5648 * @throws NullPointerException if toElement is null but the set does not
5649 * allow null elements.
5651 public SortedSet<T> headSet(T toElement)
5653 return new UnmodifiableSortedSet<T>(ss.headSet(toElement));
5657 * Returns the last (highest sorted) element in the underlying
5658 * set.
5660 * @return the last element.
5661 * @throws NoSuchElementException if the set is empty.
5663 public T last()
5665 return ss.last();
5669 * Returns a unmodifiable view of the portion of the set greater than or
5670 * equal to fromElement, and strictly less than toElement. The view is backed by
5671 * the underlying set, so changes in one show up in the other. The subset
5672 * supports all optional operations of the original.
5673 * <p>
5675 * The returned set throws an IllegalArgumentException any time an element is
5676 * used which is out of the range of fromElement and toElement. Note that the
5677 * lower endpoint is included, but the upper is not; if you want to
5678 * change the inclusion or exclusion of an endpoint, pass its successor
5679 * object in instead. For example, for Integers, you can request
5680 * <code>subSet(new Integer(lowlimit.intValue() + 1),
5681 * new Integer(highlimit.intValue() + 1))</code> to reverse
5682 * the inclusiveness of both endpoints.
5684 * @param fromElement the inclusive lower range of the subset.
5685 * @param toElement the exclusive upper range of the subset.
5686 * @return the subset.
5687 * @throws ClassCastException if fromElement or toElement is not comparable
5688 * to the set contents.
5689 * @throws IllegalArgumentException if this is a subSet, and fromElement or
5690 * toElement is out of range.
5691 * @throws NullPointerException if fromElement or toElement is null but the
5692 * set does not allow null elements.
5694 public SortedSet<T> subSet(T fromElement, T toElement)
5696 return new UnmodifiableSortedSet<T>(ss.subSet(fromElement, toElement));
5700 * Returns a unmodifiable view of the portion of the set greater than or equal to
5701 * fromElement. The view is backed by the underlying set, so changes in one show up
5702 * in the other. The subset supports all optional operations of the original.
5703 * <p>
5705 * The returned set throws an IllegalArgumentException any time an element is
5706 * used which is out of the range of fromElement. Note that the endpoint,
5707 * fromElement, is included; if you do not want this value to be included, pass its
5708 * successor object in to fromElement. For example, for Integers, you could request
5709 * <code>tailSet(new Integer(limit.intValue() + 1))</code>.
5711 * @param fromElement the inclusive lower range of the subset
5712 * @return the subset.
5713 * @throws ClassCastException if fromElement is not comparable to the set
5714 * contents.
5715 * @throws IllegalArgumentException if this is a subSet, and fromElement is
5716 * out of range.
5717 * @throws NullPointerException if fromElement is null but the set does not
5718 * allow null elements.
5720 public SortedSet<T> tailSet(T fromElement)
5722 return new UnmodifiableSortedSet<T>(ss.tailSet(fromElement));
5724 } // class UnmodifiableSortedSet
5727 * <p>
5728 * Returns a dynamically typesafe view of the given collection,
5729 * where any modification is first checked to ensure that the type
5730 * of the new data is appropriate. Although the addition of
5731 * generics and parametrically-typed collections prevents an
5732 * incorrect type of element being added to a collection at
5733 * compile-time, via static type checking, this can be overridden by
5734 * casting. In contrast, wrapping the collection within a
5735 * dynamically-typesafe wrapper, using this and associated methods,
5736 * <emph>guarantees</emph> that the collection will only contain
5737 * elements of an appropriate type (provided it only contains such
5738 * at the type of wrapping, and all subsequent access is via the
5739 * wrapper). This can be useful for debugging the cause of a
5740 * <code>ClassCastException</code> caused by erroneous casting, or
5741 * for protecting collections from corruption by external libraries.
5742 * </p>
5743 * <p>
5744 * Since the collection might be a List or a Set, and those
5745 * have incompatible equals and hashCode requirements, this relies
5746 * on Object's implementation rather than passing those calls on to
5747 * the wrapped collection. The returned Collection implements
5748 * Serializable, but can only be serialized if the collection it
5749 * wraps is likewise Serializable.
5750 * </p>
5752 * @param c the collection to wrap in a dynamically typesafe wrapper
5753 * @param type the type of elements the collection should hold.
5754 * @return a dynamically typesafe view of the collection.
5755 * @see Serializable
5756 * @since 1.5
5758 public static <E> Collection<E> checkedCollection(Collection<E> c,
5759 Class<E> type)
5761 return new CheckedCollection<E>(c, type);
5765 * The implementation of {@link #checkedCollection(Collection,Class)}. This
5766 * class name is required for compatibility with Sun's JDK serializability.
5768 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
5769 * @since 1.5
5771 private static class CheckedCollection<E>
5772 implements Collection<E>, Serializable
5775 * Compatible with JDK 1.5.
5777 private static final long serialVersionUID = 1578914078182001775L;
5780 * The wrapped collection. Package visible for use by subclasses.
5781 * @serial the real collection
5783 final Collection<E> c;
5786 * The type of the elements of this collection.
5787 * @serial the element type.
5789 final Class<E> type;
5792 * Wrap a given collection.
5793 * @param c the collection to wrap
5794 * @param type the type to wrap
5795 * @throws NullPointerException if c is null
5797 CheckedCollection(Collection<E> c, Class<E> type)
5799 this.c = c;
5800 this.type = type;
5801 if (c == null)
5802 throw new NullPointerException();
5806 * Adds the supplied object to the collection, on the condition that
5807 * it is of the correct type.
5809 * @param o the object to add.
5810 * @return <code>true</code> if the collection was modified as a result
5811 * of this action.
5812 * @throws ClassCastException if the object is not of the correct type.
5814 public boolean add(E o)
5816 if (type.isInstance(o))
5817 return c.add(o);
5818 else
5819 throw new ClassCastException("The element is of the incorrect type.");
5823 * Adds the elements of the specified collection to the backing collection,
5824 * provided they are all of the correct type.
5826 * @param coll the collection to add.
5827 * @return <code>true</code> if the collection was modified as a result
5828 * of this action.
5829 * @throws ClassCastException if <code>c</code> contained elements of an
5830 * incorrect type.
5832 public boolean addAll(Collection<? extends E> coll)
5834 Collection<E> typedColl = (Collection<E>) c;
5835 final Iterator<E> it = typedColl.iterator();
5836 while (it.hasNext())
5838 final E element = it.next();
5839 if (!type.isInstance(element))
5840 throw new ClassCastException("A member of the collection is not of the correct type.");
5842 return c.addAll(typedColl);
5846 * Removes all elements from the underlying collection.
5848 public void clear()
5850 c.clear();
5854 * Test whether the underlying collection contains a given object as one
5855 * of its elements.
5857 * @param o the element to look for.
5858 * @return <code>true</code> if the underlying collection contains at least
5859 * one element e such that
5860 * <code>o == null ? e == null : o.equals(e)</code>.
5861 * @throws ClassCastException if the type of o is not a valid type for the
5862 * underlying collection.
5863 * @throws NullPointerException if o is null and the underlying collection
5864 * doesn't support null values.
5866 public boolean contains(Object o)
5868 return c.contains(o);
5872 * Test whether the underlying collection contains every element in a given
5873 * collection.
5875 * @param coll the collection to test for.
5876 * @return <code>true</code> if for every element o in c, contains(o) would
5877 * return <code>true</code>.
5878 * @throws ClassCastException if the type of any element in c is not a
5879 * valid type for the underlying collection.
5880 * @throws NullPointerException if some element of c is null and the
5881 * underlying collection does not support
5882 * null values.
5883 * @throws NullPointerException if c itself is null.
5885 public boolean containsAll(Collection<?> coll)
5887 return c.containsAll(coll);
5891 * Tests whether the underlying collection is empty, that is,
5892 * if size() == 0.
5894 * @return <code>true</code> if this collection contains no elements.
5896 public boolean isEmpty()
5898 return c.isEmpty();
5902 * Obtain an Iterator over the underlying collection, which maintains
5903 * its checked nature.
5905 * @return a Iterator over the elements of the underlying
5906 * collection, in any order.
5908 public Iterator<E> iterator()
5910 return new CheckedIterator<E>(c.iterator(), type);
5914 * Removes the supplied object from the collection, if it exists.
5916 * @param o The object to remove.
5917 * @return <code>true</code> if the object was removed (i.e. the underlying
5918 * collection returned 1 or more instances of o).
5920 public boolean remove(Object o)
5922 return c.remove(o);
5926 * Removes all objects in the supplied collection from the backing
5927 * collection, if they exist within it.
5929 * @param coll the collection of objects to remove.
5930 * @return <code>true</code> if the collection was modified.
5932 public boolean removeAll(Collection<?> coll)
5934 return c.removeAll(coll);
5938 * Retains all objects specified by the supplied collection which exist
5939 * within the backing collection, and removes all others.
5941 * @param coll the collection of objects to retain.
5942 * @return <code>true</code> if the collection was modified.
5944 public boolean retainAll(Collection<?> coll)
5946 return c.retainAll(coll);
5950 * Retrieves the number of elements in the underlying collection.
5952 * @return the number of elements in the collection.
5954 public int size()
5956 return c.size();
5960 * Copy the current contents of the underlying collection into an array.
5962 * @return an array of type Object[] with a length equal to the size of the
5963 * underlying collection and containing the elements currently in
5964 * the underlying collection, in any order.
5966 public Object[] toArray()
5968 return c.toArray();
5972 * <p>
5973 * Copy the current contents of the underlying collection into an array. If
5974 * the array passed as an argument has length less than the size of the
5975 * underlying collection, an array of the same run-time type as a, with a
5976 * length equal to the size of the underlying collection, is allocated
5977 * using reflection.
5978 * </p>
5979 * <p>
5980 * Otherwise, a itself is used. The elements of the underlying collection
5981 * are copied into it, and if there is space in the array, the following
5982 * element is set to null. The resultant array is returned.
5983 * </p>
5984 * <p>
5985 * <emph>Note</emph>: The fact that the following element is set to null
5986 * is only useful if it is known that this collection does not contain
5987 * any null elements.
5989 * @param a the array to copy this collection into.
5990 * @return an array containing the elements currently in the underlying
5991 * collection, in any order.
5992 * @throws ArrayStoreException if the type of any element of the
5993 * collection is not a subtype of the element type of a.
5995 public <S> S[] toArray(S[] a)
5997 return c.toArray(a);
6001 * A textual representation of the unmodifiable collection.
6003 * @return The checked collection in the form of a <code>String</code>.
6005 public String toString()
6007 return c.toString();
6009 } // class CheckedCollection
6012 * The implementation of the various iterator methods in the
6013 * checked classes.
6015 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
6016 * @since 1.5
6018 private static class CheckedIterator<E>
6019 implements Iterator<E>
6022 * The wrapped iterator.
6024 private final Iterator<E> i;
6027 * The type of the elements of this collection.
6028 * @serial the element type.
6030 final Class<E> type;
6033 * Only trusted code creates a wrapper.
6034 * @param i the wrapped iterator
6035 * @param type the type of the elements within the checked list.
6037 CheckedIterator(Iterator<E> i, Class<E> type)
6039 this.i = i;
6040 this.type = type;
6044 * Obtains the next element in the underlying collection.
6046 * @return the next element in the collection.
6047 * @throws NoSuchElementException if there are no more elements.
6049 public E next()
6051 return i.next();
6055 * Tests whether there are still elements to be retrieved from the
6056 * underlying collection by <code>next()</code>. When this method
6057 * returns <code>true</code>, an exception will not be thrown on calling
6058 * <code>next()</code>.
6060 * @return <code>true</code> if there is at least one more element in the
6061 * underlying collection.
6063 public boolean hasNext()
6065 return i.hasNext();
6069 * Removes the next element from the collection.
6071 public void remove()
6073 i.remove();
6075 } // class CheckedIterator
6078 * <p>
6079 * Returns a dynamically typesafe view of the given list,
6080 * where any modification is first checked to ensure that the type
6081 * of the new data is appropriate. Although the addition of
6082 * generics and parametrically-typed collections prevents an
6083 * incorrect type of element being added to a collection at
6084 * compile-time, via static type checking, this can be overridden by
6085 * casting. In contrast, wrapping the collection within a
6086 * dynamically-typesafe wrapper, using this and associated methods,
6087 * <emph>guarantees</emph> that the collection will only contain
6088 * elements of an appropriate type (provided it only contains such
6089 * at the type of wrapping, and all subsequent access is via the
6090 * wrapper). This can be useful for debugging the cause of a
6091 * <code>ClassCastException</code> caused by erroneous casting, or
6092 * for protecting collections from corruption by external libraries.
6093 * </p>
6094 * <p>
6095 * The returned List implements Serializable, but can only be serialized if
6096 * the list it wraps is likewise Serializable. In addition, if the wrapped
6097 * list implements RandomAccess, this does too.
6098 * </p>
6100 * @param l the list to wrap
6101 * @param type the type of the elements within the checked list.
6102 * @return a dynamically typesafe view of the list
6103 * @see Serializable
6104 * @see RandomAccess
6106 public static <E> List<E> checkedList(List<E> l, Class<E> type)
6108 if (l instanceof RandomAccess)
6109 return new CheckedRandomAccessList<E>(l, type);
6110 return new CheckedList<E>(l, type);
6114 * The implementation of {@link #checkedList(List,Class)} for sequential
6115 * lists. This class name is required for compatibility with Sun's JDK
6116 * serializability.
6118 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
6119 * @since 1.5
6121 private static class CheckedList<E>
6122 extends CheckedCollection<E>
6123 implements List<E>
6126 * Compatible with JDK 1.5.
6128 private static final long serialVersionUID = 65247728283967356L;
6131 * The wrapped list; stored both here and in the superclass to avoid
6132 * excessive casting. Package visible for use by subclass.
6133 * @serial the wrapped list
6135 final List<E> list;
6138 * Wrap a given list.
6139 * @param l the list to wrap
6140 * @param type the type of the elements within the checked list.
6141 * @throws NullPointerException if l is null
6143 CheckedList(List<E> l, Class<E> type)
6145 super(l, type);
6146 list = l;
6150 * Adds the supplied element to the underlying list at the specified
6151 * index, provided it is of the right type.
6153 * @param index The index at which to place the new element.
6154 * @param o the object to add.
6155 * @throws ClassCastException if the type of the object is not a
6156 * valid type for the underlying collection.
6158 public void add(int index, E o)
6160 if (type.isInstance(o))
6161 list.add(index, o);
6162 else
6163 throw new ClassCastException("The object is of the wrong type.");
6167 * Adds the members of the supplied collection to the underlying
6168 * collection at the specified index, provided they are all of the
6169 * correct type.
6171 * @param index the index at which to place the new element.
6172 * @param coll the collections of objects to add.
6173 * @throws ClassCastException if the type of any element in c is not a
6174 * valid type for the underlying collection.
6176 public boolean addAll(int index, Collection<? extends E> coll)
6178 Collection<E> typedColl = (Collection<E>) coll;
6179 final Iterator<E> it = typedColl.iterator();
6180 while (it.hasNext())
6182 if (!type.isInstance(it.next()))
6183 throw new ClassCastException("A member of the collection is not of the correct type.");
6185 return list.addAll(index, coll);
6189 * Returns <code>true</code> if the object, o, is an instance of
6190 * <code>List</code> with the same size and elements
6191 * as the underlying list.
6193 * @param o The object to compare.
6194 * @return <code>true</code> if o is equivalent to the underlying list.
6196 public boolean equals(Object o)
6198 return list.equals(o);
6202 * Retrieves the element at a given index in the underlying list.
6204 * @param index the index of the element to be returned
6205 * @return the element at the specified index in the underlying list
6206 * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
6208 public E get(int index)
6210 return list.get(index);
6214 * Computes the hash code for the underlying list.
6215 * The exact computation is described in the documentation
6216 * of the <code>List</code> interface.
6218 * @return The hash code of the underlying list.
6219 * @see List#hashCode()
6221 public int hashCode()
6223 return list.hashCode();
6227 * Obtain the first index at which a given object is to be found in the
6228 * underlying list.
6230 * @param o the object to search for
6231 * @return the least integer n such that <code>o == null ? get(n) == null :
6232 * o.equals(get(n))</code>, or -1 if there is no such index.
6233 * @throws ClassCastException if the type of o is not a valid
6234 * type for the underlying list.
6235 * @throws NullPointerException if o is null and the underlying
6236 * list does not support null values.
6238 public int indexOf(Object o)
6240 return list.indexOf(o);
6244 * Obtain the last index at which a given object is to be found in the
6245 * underlying list.
6247 * @return the greatest integer n such that
6248 * <code>o == null ? get(n) == null : o.equals(get(n))</code>,
6249 * or -1 if there is no such index.
6250 * @throws ClassCastException if the type of o is not a valid
6251 * type for the underlying list.
6252 * @throws NullPointerException if o is null and the underlying
6253 * list does not support null values.
6255 public int lastIndexOf(Object o)
6257 return list.lastIndexOf(o);
6261 * Obtains a list iterator over the underlying list, starting at the
6262 * beginning and maintaining the checked nature of this list.
6264 * @return a <code>CheckedListIterator</code> over the elements of the
6265 * underlying list, in order, starting at the beginning.
6267 public ListIterator<E> listIterator()
6269 return new CheckedListIterator<E>(list.listIterator(), type);
6273 * Obtains a list iterator over the underlying list, starting at the
6274 * specified index and maintaining the checked nature of this list. An
6275 * initial call to <code>next()</code> will retrieve the element at the
6276 * specified index, and an initial call to <code>previous()</code> will
6277 * retrieve the element at index - 1.
6279 * @param index the position, between 0 and size() inclusive, to begin the
6280 * iteration from.
6281 * @return a <code>CheckedListIterator</code> over the elements of the
6282 * underlying list, in order, starting at the specified index.
6283 * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
6285 public ListIterator<E> listIterator(int index)
6287 return new CheckedListIterator<E>(list.listIterator(index), type);
6291 * Removes the element at the specified index.
6293 * @param index The index of the element to remove.
6294 * @return the removed element.
6296 public E remove(int index)
6298 return list.remove(index);
6302 * Replaces the element at the specified index in the underlying list
6303 * with that supplied.
6305 * @param index the index of the element to replace.
6306 * @param o the new object to place at the specified index.
6307 * @return the replaced element.
6309 public E set(int index, E o)
6311 return list.set(index, o);
6315 * Obtain a List view of a subsection of the underlying list, from
6316 * fromIndex (inclusive) to toIndex (exclusive). If the two indices
6317 * are equal, the sublist is empty. The returned list will be
6318 * checked, like this list. Changes to the elements of the
6319 * returned list will be reflected in the underlying list. The effect
6320 * of structural modifications is undefined.
6322 * @param fromIndex the index that the returned list should start from
6323 * (inclusive).
6324 * @param toIndex the index that the returned list should go
6325 * to (exclusive).
6326 * @return a List backed by a subsection of the underlying list.
6327 * @throws IndexOutOfBoundsException if fromIndex &lt; 0
6328 * || toIndex &gt; size() || fromIndex &gt; toIndex.
6330 public List<E> subList(int fromIndex, int toIndex)
6332 return checkedList(list.subList(fromIndex, toIndex), type);
6334 } // class CheckedList
6337 * The implementation of {@link #checkedList(List)} for random-access
6338 * lists. This class name is required for compatibility with Sun's JDK
6339 * serializability.
6341 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
6342 * @since 1.5
6344 private static final class CheckedRandomAccessList<E>
6345 extends CheckedList<E>
6346 implements RandomAccess
6349 * Compatible with JDK 1.5.
6351 private static final long serialVersionUID = 1638200125423088369L;
6354 * Wrap a given list.
6355 * @param l the list to wrap
6356 * @param type the type of the elements within the checked list.
6357 * @throws NullPointerException if l is null
6359 CheckedRandomAccessList(List<E> l, Class<E> type)
6361 super(l, type);
6363 } // class CheckedRandomAccessList
6366 * The implementation of {@link CheckedList#listIterator()}.
6368 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
6369 * @since 1.5
6371 private static final class CheckedListIterator<E>
6372 extends CheckedIterator<E>
6373 implements ListIterator<E>
6376 * The wrapped iterator, stored both here and in the superclass to
6377 * avoid excessive casting.
6379 private final ListIterator<E> li;
6382 * Only trusted code creates a wrapper.
6383 * @param li the wrapped iterator
6385 CheckedListIterator(ListIterator<E> li, Class<E> type)
6387 super(li, type);
6388 this.li = li;
6392 * Adds the supplied object at the current iterator position, provided
6393 * it is of the correct type.
6395 * @param o the object to add.
6396 * @throws ClassCastException if the type of the object is not a
6397 * valid type for the underlying collection.
6399 public void add(E o)
6401 if (type.isInstance(o))
6402 li.add(o);
6403 else
6404 throw new ClassCastException("The object is of the wrong type.");
6408 * Tests whether there are still elements to be retrieved from the
6409 * underlying collection by <code>previous()</code>. When this method
6410 * returns <code>true</code>, an exception will not be thrown on calling
6411 * <code>previous()</code>.
6413 * @return <code>true</code> if there is at least one more element prior
6414 * to the current position in the underlying list.
6416 public boolean hasPrevious()
6418 return li.hasPrevious();
6422 * Find the index of the element that would be returned by a call to next.
6423 * If <code>hasNext()</code> returns <code>false</code>, this returns the
6424 * list size.
6426 * @return the index of the element that would be returned by
6427 * <code>next()</code>.
6429 public int nextIndex()
6431 return li.nextIndex();
6435 * Obtains the previous element in the underlying list.
6437 * @return the previous element in the list.
6438 * @throws NoSuchElementException if there are no more prior elements.
6440 public E previous()
6442 return li.previous();
6446 * Find the index of the element that would be returned by a call to
6447 * previous. If <code>hasPrevious()</code> returns <code>false</code>,
6448 * this returns -1.
6450 * @return the index of the element that would be returned by
6451 * <code>previous()</code>.
6453 public int previousIndex()
6455 return li.previousIndex();
6459 * Sets the next element to that supplied, provided that it is of the
6460 * correct type.
6462 * @param o The new object to replace the existing one.
6463 * @throws ClassCastException if the type of the object is not a
6464 * valid type for the underlying collection.
6466 public void set(E o)
6468 if (type.isInstance(o))
6469 li.set(o);
6470 else
6471 throw new ClassCastException("The object is of the wrong type.");
6473 } // class CheckedListIterator
6476 * <p>
6477 * Returns a dynamically typesafe view of the given map,
6478 * where any modification is first checked to ensure that the type
6479 * of the new data is appropriate. Although the addition of
6480 * generics and parametrically-typed collections prevents an
6481 * incorrect type of element being added to a collection at
6482 * compile-time, via static type checking, this can be overridden by
6483 * casting. In contrast, wrapping the collection within a
6484 * dynamically-typesafe wrapper, using this and associated methods,
6485 * <emph>guarantees</emph> that the collection will only contain
6486 * elements of an appropriate type (provided it only contains such
6487 * at the type of wrapping, and all subsequent access is via the
6488 * wrapper). This can be useful for debugging the cause of a
6489 * <code>ClassCastException</code> caused by erroneous casting, or
6490 * for protecting collections from corruption by external libraries.
6491 * </p>
6492 * <p>
6493 * The returned Map implements Serializable, but can only be serialized if
6494 * the map it wraps is likewise Serializable.
6495 * </p>
6497 * @param m the map to wrap
6498 * @param keyType the dynamic type of the map's keys.
6499 * @param valueType the dynamic type of the map's values.
6500 * @return a dynamically typesafe view of the map
6501 * @see Serializable
6503 public static <K, V> Map<K, V> checkedMap(Map<K, V> m, Class<K> keyType,
6504 Class<V> valueType)
6506 return new CheckedMap<K, V>(m, keyType, valueType);
6510 * The implementation of {@link #checkedMap(Map)}. This
6511 * class name is required for compatibility with Sun's JDK serializability.
6513 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
6514 * @since 1.5
6516 private static class CheckedMap<K, V>
6517 implements Map<K, V>, Serializable
6520 * Compatible with JDK 1.5.
6522 private static final long serialVersionUID = 5742860141034234728L;
6525 * The wrapped map.
6526 * @serial the real map
6528 private final Map<K, V> m;
6531 * The type of the map's keys.
6532 * @serial the key type.
6534 final Class<K> keyType;
6537 * The type of the map's values.
6538 * @serial the value type.
6540 final Class<V> valueType;
6543 * Cache the entry set.
6545 private transient Set<Map.Entry<K, V>> entries;
6548 * Cache the key set.
6550 private transient Set<K> keys;
6553 * Cache the value collection.
6555 private transient Collection<V> values;
6558 * Wrap a given map.
6559 * @param m the map to wrap
6560 * @param keyType the dynamic type of the map's keys.
6561 * @param valueType the dynamic type of the map's values.
6562 * @throws NullPointerException if m is null
6564 CheckedMap(Map<K, V> m, Class<K> keyType, Class<V> valueType)
6566 this.m = m;
6567 this.keyType = keyType;
6568 this.valueType = valueType;
6569 if (m == null)
6570 throw new NullPointerException();
6574 * Clears all pairs from the map.
6576 public void clear()
6578 m.clear();
6582 * Returns <code>true</code> if the underlying map contains a mapping for
6583 * the given key.
6585 * @param key the key to search for
6586 * @return <code>true</code> if the map contains the key
6587 * @throws ClassCastException if the key is of an inappropriate type
6588 * @throws NullPointerException if key is <code>null</code> but the map
6589 * does not permit null keys
6591 public boolean containsKey(Object key)
6593 return m.containsKey(key);
6597 * Returns <code>true</code> if the underlying map contains at least one
6598 * mapping with the given value. In other words, it returns
6599 * <code>true</code> if a value v exists where
6600 * <code>(value == null ? v == null : value.equals(v))</code>.
6601 * This usually requires linear time.
6603 * @param value the value to search for
6604 * @return <code>true</code> if the map contains the value
6605 * @throws ClassCastException if the type of the value is not a valid type
6606 * for this map.
6607 * @throws NullPointerException if the value is null and the map doesn't
6608 * support null values.
6610 public boolean containsValue(Object value)
6612 return m.containsValue(value);
6616 * <p>
6617 * Returns a checked set view of the entries in the underlying map.
6618 * Each element in the set is a unmodifiable variant of
6619 * <code>Map.Entry</code>.
6620 * </p>
6621 * <p>
6622 * The set is backed by the map, so that changes in one show up in the
6623 * other. Modifications made while an iterator is in progress cause
6624 * undefined behavior.
6625 * </p>
6627 * @return the checked set view of all mapping entries.
6628 * @see Map.Entry
6630 public Set<Map.Entry<K, V>> entrySet()
6632 if (entries == null)
6634 Class<Map.Entry<K,V>> klass =
6635 (Class<Map.Entry<K,V>>) (Class) Map.Entry.class;
6636 entries = new CheckedEntrySet<Map.Entry<K,V>,K,V>(m.entrySet(),
6637 klass,
6638 keyType,
6639 valueType);
6641 return entries;
6645 * The implementation of {@link CheckedMap#entrySet()}. This class
6646 * is <emph>not</emph> serializable.
6648 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
6649 * @since 1.5
6651 private static final class CheckedEntrySet<E,SK,SV>
6652 extends CheckedSet<E>
6655 * The type of the map's keys.
6656 * @serial the key type.
6658 private final Class<SK> keyType;
6661 * The type of the map's values.
6662 * @serial the value type.
6664 private final Class<SV> valueType;
6667 * Wrap a given set of map entries.
6669 * @param s the set to wrap.
6670 * @param type the type of the set's entries.
6671 * @param keyType the type of the map's keys.
6672 * @param valueType the type of the map's values.
6674 CheckedEntrySet(Set<E> s, Class<E> type, Class<SK> keyType,
6675 Class<SV> valueType)
6677 super(s, type);
6678 this.keyType = keyType;
6679 this.valueType = valueType;
6682 // The iterator must return checked map entries.
6683 public Iterator<E> iterator()
6685 return new CheckedIterator<E>(c.iterator(), type)
6688 * Obtains the next element from the underlying set of
6689 * map entries.
6691 * @return the next element in the collection.
6692 * @throws NoSuchElementException if there are no more elements.
6694 public E next()
6696 final Map.Entry e = (Map.Entry) super.next();
6697 return (E) new Map.Entry()
6700 * Returns <code>true</code> if the object, o, is also a map
6701 * entry with an identical key and value.
6703 * @param o the object to compare.
6704 * @return <code>true</code> if o is an equivalent map entry.
6706 public boolean equals(Object o)
6708 return e.equals(o);
6712 * Returns the key of this map entry.
6714 * @return the key.
6716 public Object getKey()
6718 return e.getKey();
6722 * Returns the value of this map entry.
6724 * @return the value.
6726 public Object getValue()
6728 return e.getValue();
6732 * Computes the hash code of this map entry.
6733 * The computation is described in the <code>Map</code>
6734 * interface documentation.
6736 * @return the hash code of this entry.
6737 * @see Map#hashCode()
6739 public int hashCode()
6741 return e.hashCode();
6745 * Sets the value of this map entry, provided it is of the
6746 * right type.
6748 * @param value The new value.
6749 * @throws ClassCastException if the type of the value is not
6750 * a valid type for the underlying
6751 * map.
6753 public Object setValue(Object value)
6755 if (valueType.isInstance(value))
6756 return e.setValue(value);
6757 else
6758 throw new ClassCastException("The value is of the wrong type.");
6762 * Returns a textual representation of the map entry.
6764 * @return The map entry as a <code>String</code>.
6766 public String toString()
6768 return e.toString();
6774 } // class CheckedEntrySet
6777 * Returns <code>true</code> if the object, o, is also an instance
6778 * of <code>Map</code> with an equal set of map entries.
6780 * @param o The object to compare.
6781 * @return <code>true</code> if o is an equivalent map.
6783 public boolean equals(Object o)
6785 return m.equals(o);
6789 * Returns the value associated with the supplied key or
6790 * null if no such mapping exists. An ambiguity can occur
6791 * if null values are accepted by the underlying map.
6792 * In this case, <code>containsKey()</code> can be used
6793 * to separate the two possible cases of a null result.
6795 * @param key The key to look up.
6796 * @return the value associated with the key, or null if key not in map.
6797 * @throws ClassCastException if the key is an inappropriate type.
6798 * @throws NullPointerException if this map does not accept null keys.
6799 * @see #containsKey(Object)
6801 public V get(Object key)
6803 return m.get(key);
6807 * Adds a new pair to the map, provided both the key and the value are
6808 * of the correct types.
6810 * @param key The new key.
6811 * @param value The new value.
6812 * @return the previous value of the key, or null if there was no mapping.
6813 * @throws ClassCastException if the type of the key or the value is
6814 * not a valid type for the underlying map.
6816 public V put(K key, V value)
6818 if (keyType.isInstance(key))
6820 if (valueType.isInstance(value))
6821 return m.put(key,value);
6822 else
6823 throw new ClassCastException("The value is of the wrong type.");
6825 throw new ClassCastException("The key is of the wrong type.");
6829 * Computes the hash code for the underlying map, as the sum
6830 * of the hash codes of all entries.
6832 * @return The hash code of the underlying map.
6833 * @see Map.Entry#hashCode()
6835 public int hashCode()
6837 return m.hashCode();
6841 * Returns <code>true</code> if the underlying map contains no entries.
6843 * @return <code>true</code> if the map is empty.
6845 public boolean isEmpty()
6847 return m.isEmpty();
6851 * <p>
6852 * Returns a checked set view of the keys in the underlying map.
6853 * The set is backed by the map, so that changes in one show up in the
6854 * other.
6855 * </p>
6856 * <p>
6857 * Modifications made while an iterator is in progress cause undefined
6858 * behavior. These modifications are again limited to the values of
6859 * the keys.
6860 * </p>
6862 * @return the set view of all keys.
6864 public Set<K> keySet()
6866 if (keys == null)
6867 keys = new CheckedSet<K>(m.keySet(), keyType);
6868 return keys;
6872 * Adds all pairs within the supplied map to the underlying map,
6873 * provided they are all have the correct key and value types.
6875 * @param map the map, the entries of which should be added
6876 * to the underlying map.
6877 * @throws ClassCastException if the type of a key or value is
6878 * not a valid type for the underlying map.
6880 public void putAll(Map<? extends K, ? extends V> map)
6882 Map<K,V> typedMap = (Map<K,V>) map;
6883 final Iterator<Map.Entry<K,V>> it = typedMap.entrySet().iterator();
6884 while (it.hasNext())
6886 final Map.Entry<K,V> entry = it.next();
6887 if (!keyType.isInstance(entry.getKey()))
6888 throw new ClassCastException("A key is of the wrong type.");
6889 if (!valueType.isInstance(entry.getValue()))
6890 throw new ClassCastException("A value is of the wrong type.");
6892 m.putAll(typedMap);
6896 * Removes a pair from the map.
6898 * @param o The key of the entry to remove.
6899 * @return The value the key was associated with, or null
6900 * if no such mapping existed. Null is also returned
6901 * if the removed entry had a null key.
6902 * @throws UnsupportedOperationException as an unmodifiable
6903 * map does not support the <code>remove</code> operation.
6905 public V remove(Object o)
6907 return m.remove(o);
6912 * Returns the number of key-value mappings in the underlying map.
6913 * If there are more than Integer.MAX_VALUE mappings, Integer.MAX_VALUE
6914 * is returned.
6916 * @return the number of mappings.
6918 public int size()
6920 return m.size();
6924 * Returns a textual representation of the map.
6926 * @return The map in the form of a <code>String</code>.
6928 public String toString()
6930 return m.toString();
6934 * <p>
6935 * Returns a unmodifiable collection view of the values in the underlying
6936 * map. The collection is backed by the map, so that changes in one show
6937 * up in the other.
6938 * </p>
6939 * <p>
6940 * Modifications made while an iterator is in progress cause undefined
6941 * behavior. These modifications are again limited to the values of
6942 * the keys.
6943 * </p>
6945 * @return the collection view of all values.
6947 public Collection<V> values()
6949 if (values == null)
6950 values = new CheckedCollection<V>(m.values(), valueType);
6951 return values;
6953 } // class CheckedMap
6956 * <p>
6957 * Returns a dynamically typesafe view of the given set,
6958 * where any modification is first checked to ensure that the type
6959 * of the new data is appropriate. Although the addition of
6960 * generics and parametrically-typed collections prevents an
6961 * incorrect type of element being added to a collection at
6962 * compile-time, via static type checking, this can be overridden by
6963 * casting. In contrast, wrapping the collection within a
6964 * dynamically-typesafe wrapper, using this and associated methods,
6965 * <emph>guarantees</emph> that the collection will only contain
6966 * elements of an appropriate type (provided it only contains such
6967 * at the type of wrapping, and all subsequent access is via the
6968 * wrapper). This can be useful for debugging the cause of a
6969 * <code>ClassCastException</code> caused by erroneous casting, or
6970 * for protecting collections from corruption by external libraries.
6971 * </p>
6972 * <p>
6973 * The returned Set implements Serializable, but can only be serialized if
6974 * the set it wraps is likewise Serializable.
6975 * </p>
6977 * @param s the set to wrap.
6978 * @param type the type of the elements within the checked list.
6979 * @return a dynamically typesafe view of the set
6980 * @see Serializable
6982 public static <E> Set<E> checkedSet(Set<E> s, Class<E> type)
6984 return new CheckedSet<E>(s, type);
6988 * The implementation of {@link #checkedSet(Set)}. This class
6989 * name is required for compatibility with Sun's JDK serializability.
6991 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
6992 * @since 1.5
6994 private static class CheckedSet<E>
6995 extends CheckedCollection<E>
6996 implements Set<E>
6999 * Compatible with JDK 1.5.
7001 private static final long serialVersionUID = 4694047833775013803L;
7004 * Wrap a given set.
7006 * @param s the set to wrap
7007 * @throws NullPointerException if s is null
7009 CheckedSet(Set<E> s, Class<E> type)
7011 super(s, type);
7015 * Returns <code>true</code> if the object, o, is also an instance of
7016 * <code>Set</code> of the same size and with the same entries.
7018 * @return <code>true</code> if o is an equivalent set.
7020 public boolean equals(Object o)
7022 return c.equals(o);
7026 * Computes the hash code of this set, as the sum of the
7027 * hash codes of all elements within the set.
7029 * @return the hash code of the set.
7031 public int hashCode()
7033 return c.hashCode();
7035 } // class CheckedSet
7038 * <p>
7039 * Returns a dynamically typesafe view of the given sorted map,
7040 * where any modification is first checked to ensure that the type
7041 * of the new data is appropriate. Although the addition of
7042 * generics and parametrically-typed collections prevents an
7043 * incorrect type of element being added to a collection at
7044 * compile-time, via static type checking, this can be overridden by
7045 * casting. In contrast, wrapping the collection within a
7046 * dynamically-typesafe wrapper, using this and associated methods,
7047 * <emph>guarantees</emph> that the collection will only contain
7048 * elements of an appropriate type (provided it only contains such
7049 * at the type of wrapping, and all subsequent access is via the
7050 * wrapper). This can be useful for debugging the cause of a
7051 * <code>ClassCastException</code> caused by erroneous casting, or
7052 * for protecting collections from corruption by external libraries.
7053 * </p>
7054 * <p>
7055 * The returned SortedMap implements Serializable, but can only be
7056 * serialized if the map it wraps is likewise Serializable.
7057 * </p>
7059 * @param m the map to wrap.
7060 * @param keyType the dynamic type of the map's keys.
7061 * @param valueType the dynamic type of the map's values.
7062 * @return a dynamically typesafe view of the map
7063 * @see Serializable
7065 public static <K, V> SortedMap<K, V> checkedSortedMap(SortedMap<K, V> m,
7066 Class<K> keyType,
7067 Class<V> valueType)
7069 return new CheckedSortedMap<K, V>(m, keyType, valueType);
7073 * The implementation of {@link #checkedSortedMap(SortedMap,Class,Class)}.
7074 * This class name is required for compatibility with Sun's JDK
7075 * serializability.
7077 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
7079 private static class CheckedSortedMap<K, V>
7080 extends CheckedMap<K, V>
7081 implements SortedMap<K, V>
7084 * Compatible with JDK 1.5.
7086 private static final long serialVersionUID = 1599671320688067438L;
7089 * The wrapped map; stored both here and in the superclass to avoid
7090 * excessive casting.
7091 * @serial the wrapped map
7093 private final SortedMap<K, V> sm;
7096 * Wrap a given map.
7098 * @param sm the map to wrap
7099 * @param keyType the dynamic type of the map's keys.
7100 * @param valueType the dynamic type of the map's values.
7101 * @throws NullPointerException if sm is null
7103 CheckedSortedMap(SortedMap<K, V> sm, Class<K> keyType, Class<V> valueType)
7105 super(sm, keyType, valueType);
7106 this.sm = sm;
7110 * Returns the comparator used in sorting the underlying map,
7111 * or null if it is the keys' natural ordering.
7113 * @return the sorting comparator.
7115 public Comparator<? super K> comparator()
7117 return sm.comparator();
7121 * Returns the first (lowest sorted) key in the map.
7123 * @return the first key.
7124 * @throws NoSuchElementException if this map is empty.
7126 public K firstKey()
7128 return sm.firstKey();
7132 * <p>
7133 * Returns a checked view of the portion of the map strictly less
7134 * than toKey. The view is backed by the underlying map, so changes in
7135 * one show up in the other. The submap supports all optional operations
7136 * of the original. This operation is equivalent to
7137 * <code>subMap(firstKey(), toKey)</code>.
7138 * </p>
7139 * <p>
7140 * The returned map throws an IllegalArgumentException any time a key is
7141 * used which is out of the range of toKey. Note that the endpoint, toKey,
7142 * is not included; if you want this value to be included, pass its
7143 * successor object in to toKey. For example, for Integers, you could
7144 * request <code>headMap(new Integer(limit.intValue() + 1))</code>.
7145 * </p>
7147 * @param toKey the exclusive upper range of the submap.
7148 * @return the submap.
7149 * @throws ClassCastException if toKey is not comparable to the map
7150 * contents.
7151 * @throws IllegalArgumentException if this is a subMap, and toKey is out
7152 * of range.
7153 * @throws NullPointerException if toKey is null but the map does not allow
7154 * null keys.
7156 public SortedMap<K, V> headMap(K toKey)
7158 return new CheckedSortedMap<K, V>(sm.headMap(toKey), keyType, valueType);
7162 * Returns the last (highest sorted) key in the map.
7164 * @return the last key.
7165 * @throws NoSuchElementException if this map is empty.
7167 public K lastKey()
7169 return sm.lastKey();
7173 * <p>
7174 * Returns a checked view of the portion of the map greater than or
7175 * equal to fromKey, and strictly less than toKey. The view is backed by
7176 * the underlying map, so changes in one show up in the other. The submap
7177 * supports all optional operations of the original.
7178 * </p>
7179 * <p>
7180 * The returned map throws an IllegalArgumentException any time a key is
7181 * used which is out of the range of fromKey and toKey. Note that the
7182 * lower endpoint is included, but the upper is not; if you want to
7183 * change the inclusion or exclusion of an endpoint, pass its successor
7184 * object in instead. For example, for Integers, you could request
7185 * <code>subMap(new Integer(lowlimit.intValue() + 1),
7186 * new Integer(highlimit.intValue() + 1))</code> to reverse
7187 * the inclusiveness of both endpoints.
7188 * </p>
7190 * @param fromKey the inclusive lower range of the submap.
7191 * @param toKey the exclusive upper range of the submap.
7192 * @return the submap.
7193 * @throws ClassCastException if fromKey or toKey is not comparable to
7194 * the map contents.
7195 * @throws IllegalArgumentException if this is a subMap, and fromKey or
7196 * toKey is out of range.
7197 * @throws NullPointerException if fromKey or toKey is null but the map
7198 * does not allow null keys.
7200 public SortedMap<K, V> subMap(K fromKey, K toKey)
7202 return new CheckedSortedMap<K, V>(sm.subMap(fromKey, toKey), keyType,
7203 valueType);
7207 * <p>
7208 * Returns a checked view of the portion of the map greater than or
7209 * equal to fromKey. The view is backed by the underlying map, so changes
7210 * in one show up in the other. The submap supports all optional operations
7211 * of the original.
7212 * </p>
7213 * <p>
7214 * The returned map throws an IllegalArgumentException any time a key is
7215 * used which is out of the range of fromKey. Note that the endpoint,
7216 * fromKey, is included; if you do not want this value to be included,
7217 * pass its successor object in to fromKey. For example, for Integers,
7218 * you could request
7219 * <code>tailMap(new Integer(limit.intValue() + 1))</code>.
7220 * </p>
7222 * @param fromKey the inclusive lower range of the submap
7223 * @return the submap
7224 * @throws ClassCastException if fromKey is not comparable to the map
7225 * contents
7226 * @throws IllegalArgumentException if this is a subMap, and fromKey is out
7227 * of range
7228 * @throws NullPointerException if fromKey is null but the map does not
7229 * allow null keys
7231 public SortedMap<K, V> tailMap(K fromKey)
7233 return new CheckedSortedMap<K, V>(sm.tailMap(fromKey), keyType,
7234 valueType);
7236 } // class CheckedSortedMap
7239 * <p>
7240 * Returns a dynamically typesafe view of the given sorted set,
7241 * where any modification is first checked to ensure that the type
7242 * of the new data is appropriate. Although the addition of
7243 * generics and parametrically-typed collections prevents an
7244 * incorrect type of element being added to a collection at
7245 * compile-time, via static type checking, this can be overridden by
7246 * casting. In contrast, wrapping the collection within a
7247 * dynamically-typesafe wrapper, using this and associated methods,
7248 * <emph>guarantees</emph> that the collection will only contain
7249 * elements of an appropriate type (provided it only contains such
7250 * at the type of wrapping, and all subsequent access is via the
7251 * wrapper). This can be useful for debugging the cause of a
7252 * <code>ClassCastException</code> caused by erroneous casting, or
7253 * for protecting collections from corruption by external libraries.
7254 * </p>
7255 * <p>
7256 * The returned SortedSet implements Serializable, but can only be
7257 * serialized if the set it wraps is likewise Serializable.
7258 * </p>
7260 * @param s the set to wrap.
7261 * @param type the type of the set's elements.
7262 * @return a dynamically typesafe view of the set
7263 * @see Serializable
7265 public static <E> SortedSet<E> checkedSortedSet(SortedSet<E> s,
7266 Class<E> type)
7268 return new CheckedSortedSet<E>(s, type);
7272 * The implementation of {@link #checkedSortedSet(SortedSet,Class)}. This
7273 * class name is required for compatibility with Sun's JDK serializability.
7275 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
7276 * @since 1.5
7278 private static class CheckedSortedSet<E>
7279 extends CheckedSet<E>
7280 implements SortedSet<E>
7283 * Compatible with JDK 1.4.
7285 private static final long serialVersionUID = 1599911165492914959L;
7288 * The wrapped set; stored both here and in the superclass to avoid
7289 * excessive casting.
7291 * @serial the wrapped set
7293 private SortedSet<E> ss;
7296 * Wrap a given set.
7298 * @param ss the set to wrap.
7299 * @param type the type of the set's elements.
7300 * @throws NullPointerException if ss is null
7302 CheckedSortedSet(SortedSet<E> ss, Class<E> type)
7304 super(ss, type);
7305 this.ss = ss;
7309 * Returns the comparator used in sorting the underlying set,
7310 * or null if it is the elements' natural ordering.
7312 * @return the sorting comparator
7314 public Comparator<? super E> comparator()
7316 return ss.comparator();
7320 * Returns the first (lowest sorted) element in the underlying
7321 * set.
7323 * @return the first element.
7324 * @throws NoSuchElementException if the set is empty.
7326 public E first()
7328 return ss.first();
7332 * <p>
7333 * Returns a checked view of the portion of the set strictly
7334 * less than toElement. The view is backed by the underlying set,
7335 * so changes in one show up in the other. The subset supports
7336 * all optional operations of the original. This operation
7337 * is equivalent to <code>subSet(first(), toElement)</code>.
7338 * </p>
7339 * <p>
7340 * The returned set throws an IllegalArgumentException any time an
7341 * element is used which is out of the range of toElement. Note that
7342 * the endpoint, toElement, is not included; if you want this value
7343 * included, pass its successor object in to toElement. For example,
7344 * for Integers, you could request
7345 * <code>headSet(new Integer(limit.intValue() + 1))</code>.
7346 * </p>
7348 * @param toElement the exclusive upper range of the subset
7349 * @return the subset.
7350 * @throws ClassCastException if toElement is not comparable to the set
7351 * contents.
7352 * @throws IllegalArgumentException if this is a subSet, and toElement is
7353 * out of range.
7354 * @throws NullPointerException if toElement is null but the set does not
7355 * allow null elements.
7357 public SortedSet<E> headSet(E toElement)
7359 return new CheckedSortedSet<E>(ss.headSet(toElement), type);
7363 * Returns the last (highest sorted) element in the underlying
7364 * set.
7366 * @return the last element.
7367 * @throws NoSuchElementException if the set is empty.
7369 public E last()
7371 return ss.last();
7375 * <p>
7376 * Returns a checked view of the portion of the set greater than or
7377 * equal to fromElement, and strictly less than toElement. The view is
7378 * backed by the underlying set, so changes in one show up in the other.
7379 * The subset supports all optional operations of the original.
7380 * </p>
7381 * <p>
7382 * The returned set throws an IllegalArgumentException any time an
7383 * element is used which is out of the range of fromElement and toElement.
7384 * Note that the lower endpoint is included, but the upper is not; if you
7385 * want to change the inclusion or exclusion of an endpoint, pass its
7386 * successor object in instead. For example, for Integers, you can request
7387 * <code>subSet(new Integer(lowlimit.intValue() + 1),
7388 * new Integer(highlimit.intValue() + 1))</code> to reverse
7389 * the inclusiveness of both endpoints.
7390 * </p>
7392 * @param fromElement the inclusive lower range of the subset.
7393 * @param toElement the exclusive upper range of the subset.
7394 * @return the subset.
7395 * @throws ClassCastException if fromElement or toElement is not comparable
7396 * to the set contents.
7397 * @throws IllegalArgumentException if this is a subSet, and fromElement or
7398 * toElement is out of range.
7399 * @throws NullPointerException if fromElement or toElement is null but the
7400 * set does not allow null elements.
7402 public SortedSet<E> subSet(E fromElement, E toElement)
7404 return new CheckedSortedSet<E>(ss.subSet(fromElement, toElement), type);
7408 * <p>
7409 * Returns a checked view of the portion of the set greater than or equal
7410 * to fromElement. The view is backed by the underlying set, so changes in
7411 * one show up in the other. The subset supports all optional operations
7412 * of the original.
7413 * </p>
7414 * <p>
7415 * The returned set throws an IllegalArgumentException any time an
7416 * element is used which is out of the range of fromElement. Note that
7417 * the endpoint, fromElement, is included; if you do not want this value
7418 * to be included, pass its successor object in to fromElement. For
7419 * example, for Integers, you could request
7420 * <code>tailSet(new Integer(limit.intValue() + 1))</code>.
7421 * </p>
7423 * @param fromElement the inclusive lower range of the subset
7424 * @return the subset.
7425 * @throws ClassCastException if fromElement is not comparable to the set
7426 * contents.
7427 * @throws IllegalArgumentException if this is a subSet, and fromElement is
7428 * out of range.
7429 * @throws NullPointerException if fromElement is null but the set does not
7430 * allow null elements.
7432 public SortedSet<E> tailSet(E fromElement)
7434 return new CheckedSortedSet<E>(ss.tailSet(fromElement), type);
7436 } // class CheckedSortedSet
7439 * Returns a view of a {@link Deque} as a stack or LIFO (Last-In-First-Out)
7440 * {@link Queue}. Each call to the LIFO queue corresponds to one
7441 * equivalent method call to the underlying deque, with the exception
7442 * of {@link Collection#addAll(Collection)}, which is emulated by a series
7443 * of {@link Deque#push(E)} calls.
7445 * @param deque the deque to convert to a LIFO queue.
7446 * @return a LIFO queue.
7447 * @since 1.6
7449 public static <T> Queue<T> asLifoQueue(Deque<T> deque)
7451 return new LIFOQueue<T>(deque);
7455 * Returns a set backed by the supplied map. The resulting set
7456 * has the same performance, concurrency and ordering characteristics
7457 * as the original map. The supplied map must be empty and should not
7458 * be used after the set is created. Each call to the set corresponds
7459 * to one equivalent method call to the underlying map, with the exception
7460 * of {@link Set#addAll(Collection)} which is emulated by a series of
7461 * calls to <code>put</code>.
7463 * @param map the map to convert to a set.
7464 * @return a set backed by the supplied map.
7465 * @throws IllegalArgumentException if the map is not empty.
7466 * @since 1.6
7468 public static <E> Set<E> newSetFromMap(Map<E,Boolean> map)
7470 return new MapSet<E>(map);
7474 * The implementation of {@link #asLIFOQueue(Deque)}.
7476 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
7477 * @since 1.6
7479 private static class LIFOQueue<T>
7480 extends AbstractQueue<T>
7484 * The backing deque.
7486 private Deque<T> deque;
7489 * Constructs a new {@link LIFOQueue} with the specified
7490 * backing {@link Deque}.
7492 * @param deque the backing deque.
7494 public LIFOQueue(Deque<T> deque)
7496 this.deque = deque;
7499 public boolean add(T e)
7501 return deque.offerFirst(e);
7504 public boolean addAll(Collection<? extends T> c)
7506 boolean result = false;
7507 final Iterator<? extends T> it = c.iterator();
7508 while (it.hasNext())
7509 result |= deque.offerFirst(it.next());
7510 return result;
7513 public void clear()
7515 deque.clear();
7518 public boolean isEmpty()
7520 return deque.isEmpty();
7523 public Iterator<T> iterator()
7525 return deque.iterator();
7528 public boolean offer(T e)
7530 return deque.offerFirst(e);
7533 public T peek()
7535 return deque.peek();
7538 public T poll()
7540 return deque.poll();
7543 public int size()
7545 return deque.size();
7547 } // class LIFOQueue
7550 * The implementation of {@link #newSetFromMap(Map)}.
7552 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
7553 * @since 1.6
7555 private static class MapSet<E>
7556 extends AbstractSet<E>
7560 * The backing map.
7562 private Map<E,Boolean> map;
7565 * Constructs a new {@link MapSet} using the specified
7566 * backing {@link Map}.
7568 * @param map the backing map.
7569 * @throws IllegalArgumentException if the map is not empty.
7571 public MapSet(Map<E,Boolean> map)
7573 if (!map.isEmpty())
7574 throw new IllegalArgumentException("The map must be empty.");
7575 this.map = map;
7578 public boolean add(E e)
7580 return map.put(e, true) == null;
7583 public boolean addAll(Collection<? extends E> c)
7585 boolean result = false;
7586 final Iterator<? extends E> it = c.iterator();
7587 while (it.hasNext())
7588 result |= (map.put(it.next(), true) == null);
7589 return result;
7592 public void clear()
7594 map.clear();
7597 public boolean contains(Object o)
7599 return map.containsKey(o);
7602 public boolean isEmpty()
7604 return map.isEmpty();
7607 public Iterator<E> iterator()
7609 return map.keySet().iterator();
7612 public boolean remove(Object o)
7614 return map.remove(o) != null;
7617 public int size()
7619 return map.size();
7621 } // class MapSet
7623 } // class Collections