ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/Collections.java
(Generate patch)

Comparing jsr166/src/main/java/util/Collections.java (file contents):
Revision 1.20 by jsr166, Wed Jan 11 00:57:12 2006 UTC vs.
Revision 1.33 by jsr166, Sun May 18 23:47:55 2008 UTC

# Line 1 | Line 1
1   /*
2 < * %W% %E%
2 > * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
3 > * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4   *
5 < * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
6 < * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
5 > * This code is free software; you can redistribute it and/or modify it
6 > * under the terms of the GNU General Public License version 2 only, as
7 > * published by the Free Software Foundation.  Sun designates this
8 > * particular file as subject to the "Classpath" exception as provided
9 > * by Sun in the LICENSE file that accompanied this code.
10 > *
11 > * This code is distributed in the hope that it will be useful, but WITHOUT
12 > * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 > * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 > * version 2 for more details (a copy is included in the LICENSE file that
15 > * accompanied this code).
16 > *
17 > * You should have received a copy of the GNU General Public License version
18 > * 2 along with this work; if not, write to the Free Software Foundation,
19 > * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 > *
21 > * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 > * CA 95054 USA or visit www.sun.com if you need additional information or
23 > * have any questions.
24   */
25  
26   package java.util;
9 import java.util.*; // for javadoc (till 6280605 is fixed)
27   import java.io.Serializable;
28   import java.io.ObjectOutputStream;
29   import java.io.IOException;
# Line 39 | Line 56 | import java.lang.reflect.Array;
56   * already sorted may or may not throw <tt>UnsupportedOperationException</tt>.
57   *
58   * <p>This class is a member of the
59 < * <a href="{@docRoot}/../guide/collections/index.html">
59 > * <a href="{@docRoot}/../technotes/guides/collections/index.html">
60   * Java Collections Framework</a>.
61   *
62   * @author  Josh Bloch
63   * @author  Neal Gafter
64   * @version %I%, %G%
65 < * @see     Collection
66 < * @see     Set
67 < * @see     List
68 < * @see     Map
65 > * @see     Collection
66 > * @see     Set
67 > * @see     List
68 > * @see     Map
69   * @since   1.2
70   */
71  
# Line 108 | Line 125 | public class Collections {
125       *
126       * @param  list the list to be sorted.
127       * @throws ClassCastException if the list contains elements that are not
128 <     *         <i>mutually comparable</i> (for example, strings and integers).
128 >     *         <i>mutually comparable</i> (for example, strings and integers).
129       * @throws UnsupportedOperationException if the specified list's
130 <     *         list-iterator does not support the <tt>set</tt> operation.
130 >     *         list-iterator does not support the <tt>set</tt> operation.
131       * @see Comparable
132       */
133      public static <T extends Comparable<? super T>> void sort(List<T> list) {
134 <        Object[] a = list.toArray();
135 <        Arrays.sort(a);
136 <        ListIterator<T> i = list.listIterator();
137 <        for (int j=0; j<a.length; j++) {
138 <            i.next();
139 <            i.set((T)a[j]);
140 <        }
134 >        Object[] a = list.toArray();
135 >        Arrays.sort(a);
136 >        ListIterator<T> i = list.listIterator();
137 >        for (int j=0; j<a.length; j++) {
138 >            i.next();
139 >            i.set((T)a[j]);
140 >        }
141      }
142  
143      /**
# Line 150 | Line 167 | public class Collections {
167       *        <tt>null</tt> value indicates that the elements' <i>natural
168       *        ordering</i> should be used.
169       * @throws ClassCastException if the list contains elements that are not
170 <     *         <i>mutually comparable</i> using the specified comparator.
170 >     *         <i>mutually comparable</i> using the specified comparator.
171       * @throws UnsupportedOperationException if the specified list's
172 <     *         list-iterator does not support the <tt>set</tt> operation.
172 >     *         list-iterator does not support the <tt>set</tt> operation.
173       * @see Comparator
174       */
175      public static <T> void sort(List<T> list, Comparator<? super T> c) {
176 <        Object[] a = list.toArray();
177 <        Arrays.sort(a, (Comparator)c);
178 <        ListIterator i = list.listIterator();
179 <        for (int j=0; j<a.length; j++) {
180 <            i.next();
181 <            i.set(a[j]);
182 <        }
176 >        Object[] a = list.toArray();
177 >        Arrays.sort(a, (Comparator)c);
178 >        ListIterator i = list.listIterator();
179 >        for (int j=0; j<a.length; j++) {
180 >            i.next();
181 >            i.set(a[j]);
182 >        }
183      }
184  
185  
186      /**
187       * Searches the specified list for the specified object using the binary
188       * search algorithm.  The list must be sorted into ascending order
189 <     * according to the <i>natural ordering</i> of its elements (as by the
190 <     * <tt>sort(List)</tt> method, above) prior to making this call.  If it is
191 <     * not sorted, the results are undefined.  If the list contains multiple
192 <     * elements equal to the specified object, there is no guarantee which one
193 <     * will be found.<p>
189 >     * according to the {@linkplain Comparable natural ordering} of its
190 >     * elements (as by the {@link #sort(List)} method) prior to making this
191 >     * call.  If it is not sorted, the results are undefined.  If the list
192 >     * contains multiple elements equal to the specified object, there is no
193 >     * guarantee which one will be found.
194       *
195 <     * This method runs in log(n) time for a "random access" list (which
195 >     * <p>This method runs in log(n) time for a "random access" list (which
196       * provides near-constant-time positional access).  If the specified list
197       * does not implement the {@link RandomAccess} interface and is large,
198       * this method will do an iterator-based binary search that performs
# Line 184 | Line 201 | public class Collections {
201       * @param  list the list to be searched.
202       * @param  key the key to be searched for.
203       * @return the index of the search key, if it is contained in the list;
204 <     *         otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>.  The
205 <     *         <i>insertion point</i> is defined as the point at which the
206 <     *         key would be inserted into the list: the index of the first
207 <     *         element greater than the key, or <tt>list.size()</tt>, if all
208 <     *         elements in the list are less than the specified key.  Note
209 <     *         that this guarantees that the return value will be &gt;= 0 if
210 <     *         and only if the key is found.
204 >     *         otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>.  The
205 >     *         <i>insertion point</i> is defined as the point at which the
206 >     *         key would be inserted into the list: the index of the first
207 >     *         element greater than the key, or <tt>list.size()</tt> if all
208 >     *         elements in the list are less than the specified key.  Note
209 >     *         that this guarantees that the return value will be &gt;= 0 if
210 >     *         and only if the key is found.
211       * @throws ClassCastException if the list contains elements that are not
212 <     *         <i>mutually comparable</i> (for example, strings and
213 <     *         integers), or the search key in not mutually comparable
214 <     *         with the elements of the list.
198 <     * @see    Comparable
199 <     * @see #sort(List)
212 >     *         <i>mutually comparable</i> (for example, strings and
213 >     *         integers), or the search key is not mutually comparable
214 >     *         with the elements of the list.
215       */
216      public static <T>
217      int binarySearch(List<? extends Comparable<? super T>> list, T key) {
# Line 209 | Line 224 | public class Collections {
224      private static <T>
225      int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key)
226      {
227 <        int low = 0;
228 <        int high = list.size()-1;
227 >        int low = 0;
228 >        int high = list.size()-1;
229 >
230 >        while (low <= high) {
231 >            int mid = (low + high) >>> 1;
232 >            Comparable<? super T> midVal = list.get(mid);
233 >            int cmp = midVal.compareTo(key);
234  
235 <        while (low <= high) {
236 <            int mid = (low + high) >> 1;
237 <            Comparable<? super T> midVal = list.get(mid);
238 <            int cmp = midVal.compareTo(key);
239 <
240 <            if (cmp < 0)
241 <                low = mid + 1;
242 <            else if (cmp > 0)
223 <                high = mid - 1;
224 <            else
225 <                return mid; // key found
226 <        }
227 <        return -(low + 1);  // key not found
235 >            if (cmp < 0)
236 >                low = mid + 1;
237 >            else if (cmp > 0)
238 >                high = mid - 1;
239 >            else
240 >                return mid; // key found
241 >        }
242 >        return -(low + 1);  // key not found
243      }
244  
245      private static <T>
246      int iteratorBinarySearch(List<? extends Comparable<? super T>> list, T key)
247      {
248 <        int low = 0;
249 <        int high = list.size()-1;
248 >        int low = 0;
249 >        int high = list.size()-1;
250          ListIterator<? extends Comparable<? super T>> i = list.listIterator();
251  
252          while (low <= high) {
253 <            int mid = (low + high) >> 1;
253 >            int mid = (low + high) >>> 1;
254              Comparable<? super T> midVal = get(i, mid);
255              int cmp = midVal.compareTo(key);
256  
# Line 254 | Line 269 | public class Collections {
269       * list listIterator.
270       */
271      private static <T> T get(ListIterator<? extends T> i, int index) {
272 <        T obj = null;
272 >        T obj = null;
273          int pos = i.nextIndex();
274          if (pos <= index) {
275              do {
# Line 271 | Line 286 | public class Collections {
286      /**
287       * Searches the specified list for the specified object using the binary
288       * search algorithm.  The list must be sorted into ascending order
289 <     * according to the specified comparator (as by the <tt>Sort(List,
290 <     * Comparator)</tt> method, above), prior to making this call.  If it is
289 >     * according to the specified comparator (as by the
290 >     * {@link #sort(List, Comparator) sort(List, Comparator)}
291 >     * method), prior to making this call.  If it is
292       * not sorted, the results are undefined.  If the list contains multiple
293       * elements equal to the specified object, there is no guarantee which one
294 <     * will be found.<p>
294 >     * will be found.
295       *
296 <     * This method runs in log(n) time for a "random access" list (which
296 >     * <p>This method runs in log(n) time for a "random access" list (which
297       * provides near-constant-time positional access).  If the specified list
298       * does not implement the {@link RandomAccess} interface and is large,
299       * this method will do an iterator-based binary search that performs
# Line 285 | Line 301 | public class Collections {
301       *
302       * @param  list the list to be searched.
303       * @param  key the key to be searched for.
304 <     * @param  c the comparator by which the list is ordered.  A
305 <     *        <tt>null</tt> value indicates that the elements' <i>natural
306 <     *        ordering</i> should be used.
304 >     * @param  c the comparator by which the list is ordered.
305 >     *         A <tt>null</tt> value indicates that the elements'
306 >     *         {@linkplain Comparable natural ordering} should be used.
307       * @return the index of the search key, if it is contained in the list;
308 <     *         otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>.  The
309 <     *         <i>insertion point</i> is defined as the point at which the
310 <     *         key would be inserted into the list: the index of the first
311 <     *         element greater than the key, or <tt>list.size()</tt>, if all
312 <     *         elements in the list are less than the specified key.  Note
313 <     *         that this guarantees that the return value will be &gt;= 0 if
314 <     *         and only if the key is found.
308 >     *         otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>.  The
309 >     *         <i>insertion point</i> is defined as the point at which the
310 >     *         key would be inserted into the list: the index of the first
311 >     *         element greater than the key, or <tt>list.size()</tt> if all
312 >     *         elements in the list are less than the specified key.  Note
313 >     *         that this guarantees that the return value will be &gt;= 0 if
314 >     *         and only if the key is found.
315       * @throws ClassCastException if the list contains elements that are not
316 <     *         <i>mutually comparable</i> using the specified comparator,
317 <     *         or the search key in not mutually comparable with the
318 <     *         elements of the list using this comparator.
303 <     * @see    Comparable
304 <     * @see #sort(List, Comparator)
316 >     *         <i>mutually comparable</i> using the specified comparator,
317 >     *         or the search key is not mutually comparable with the
318 >     *         elements of the list using this comparator.
319       */
320      public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c) {
321          if (c==null)
# Line 314 | Line 328 | public class Collections {
328      }
329  
330      private static <T> int indexedBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) {
331 <        int low = 0;
332 <        int high = l.size()-1;
331 >        int low = 0;
332 >        int high = l.size()-1;
333 >
334 >        while (low <= high) {
335 >            int mid = (low + high) >>> 1;
336 >            T midVal = l.get(mid);
337 >            int cmp = c.compare(midVal, key);
338  
339 <        while (low <= high) {
340 <            int mid = (low + high) >> 1;
341 <            T midVal = l.get(mid);
342 <            int cmp = c.compare(midVal, key);
343 <
344 <            if (cmp < 0)
345 <                low = mid + 1;
346 <            else if (cmp > 0)
328 <                high = mid - 1;
329 <            else
330 <                return mid; // key found
331 <        }
332 <        return -(low + 1);  // key not found
339 >            if (cmp < 0)
340 >                low = mid + 1;
341 >            else if (cmp > 0)
342 >                high = mid - 1;
343 >            else
344 >                return mid; // key found
345 >        }
346 >        return -(low + 1);  // key not found
347      }
348  
349      private static <T> int iteratorBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) {
350 <        int low = 0;
351 <        int high = l.size()-1;
350 >        int low = 0;
351 >        int high = l.size()-1;
352          ListIterator<? extends T> i = l.listIterator();
353  
354          while (low <= high) {
355 <            int mid = (low + high) >> 1;
355 >            int mid = (low + high) >>> 1;
356              T midVal = get(i, mid);
357              int cmp = c.compare(midVal, key);
358  
# Line 373 | Line 387 | public class Collections {
387              ListIterator fwd = list.listIterator();
388              ListIterator rev = list.listIterator(size);
389              for (int i=0, mid=list.size()>>1; i<mid; i++) {
390 <                Object tmp = fwd.next();
390 >                Object tmp = fwd.next();
391                  fwd.set(rev.previous());
392                  rev.set(tmp);
393              }
# Line 474 | Line 488 | public class Collections {
488       * @since 1.4
489       */
490      public static void swap(List<?> list, int i, int j) {
491 <        final List l = list;
492 <        l.set(i, l.set(j, l.get(i)));
491 >        final List l = list;
492 >        l.set(i, l.set(j, l.get(i)));
493      }
494  
495      /**
# Line 496 | Line 510 | public class Collections {
510       * @param  list the list to be filled with the specified element.
511       * @param  obj The element with which to fill the specified list.
512       * @throws UnsupportedOperationException if the specified list or its
513 <     *         list-iterator does not support the <tt>set</tt> operation.
513 >     *         list-iterator does not support the <tt>set</tt> operation.
514       */
515      public static <T> void fill(List<? super T> list, T obj) {
516          int size = list.size();
# Line 540 | Line 554 | public class Collections {
554                  dest.set(i, src.get(i));
555          } else {
556              ListIterator<? super T> di=dest.listIterator();
557 <            ListIterator<? extends T> si=src.listIterator();
557 >            ListIterator<? extends T> si=src.listIterator();
558              for (int i=0; i<srcSize; i++) {
559                  di.next();
560                  di.set(si.next());
# Line 564 | Line 578 | public class Collections {
578       * @return the minimum element of the given collection, according
579       *         to the <i>natural ordering</i> of its elements.
580       * @throws ClassCastException if the collection contains elements that are
581 <     *         not <i>mutually comparable</i> (for example, strings and
582 <     *         integers).
581 >     *         not <i>mutually comparable</i> (for example, strings and
582 >     *         integers).
583       * @throws NoSuchElementException if the collection is empty.
584       * @see Comparable
585       */
586      public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) {
587 <        Iterator<? extends T> i = coll.iterator();
588 <        T candidate = i.next();
587 >        Iterator<? extends T> i = coll.iterator();
588 >        T candidate = i.next();
589  
590          while (i.hasNext()) {
591 <            T next = i.next();
592 <            if (next.compareTo(candidate) < 0)
593 <                candidate = next;
594 <        }
595 <        return candidate;
591 >            T next = i.next();
592 >            if (next.compareTo(candidate) < 0)
593 >                candidate = next;
594 >        }
595 >        return candidate;
596      }
597  
598      /**
# Line 599 | Line 613 | public class Collections {
613       * @return the minimum element of the given collection, according
614       *         to the specified comparator.
615       * @throws ClassCastException if the collection contains elements that are
616 <     *         not <i>mutually comparable</i> using the specified comparator.
616 >     *         not <i>mutually comparable</i> using the specified comparator.
617       * @throws NoSuchElementException if the collection is empty.
618       * @see Comparable
619       */
# Line 607 | Line 621 | public class Collections {
621          if (comp==null)
622              return (T)min((Collection<SelfComparable>) (Collection) coll);
623  
624 <        Iterator<? extends T> i = coll.iterator();
625 <        T candidate = i.next();
624 >        Iterator<? extends T> i = coll.iterator();
625 >        T candidate = i.next();
626  
627          while (i.hasNext()) {
628 <            T next = i.next();
629 <            if (comp.compare(next, candidate) < 0)
630 <                candidate = next;
631 <        }
632 <        return candidate;
628 >            T next = i.next();
629 >            if (comp.compare(next, candidate) < 0)
630 >                candidate = next;
631 >        }
632 >        return candidate;
633      }
634  
635      /**
# Line 634 | Line 648 | public class Collections {
648       * @return the maximum element of the given collection, according
649       *         to the <i>natural ordering</i> of its elements.
650       * @throws ClassCastException if the collection contains elements that are
651 <     *         not <i>mutually comparable</i> (for example, strings and
651 >     *         not <i>mutually comparable</i> (for example, strings and
652       *         integers).
653       * @throws NoSuchElementException if the collection is empty.
654       * @see Comparable
655       */
656      public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
657 <        Iterator<? extends T> i = coll.iterator();
658 <        T candidate = i.next();
657 >        Iterator<? extends T> i = coll.iterator();
658 >        T candidate = i.next();
659  
660          while (i.hasNext()) {
661 <            T next = i.next();
662 <            if (next.compareTo(candidate) > 0)
663 <                candidate = next;
664 <        }
665 <        return candidate;
661 >            T next = i.next();
662 >            if (next.compareTo(candidate) > 0)
663 >                candidate = next;
664 >        }
665 >        return candidate;
666      }
667  
668      /**
# Line 669 | Line 683 | public class Collections {
683       * @return the maximum element of the given collection, according
684       *         to the specified comparator.
685       * @throws ClassCastException if the collection contains elements that are
686 <     *         not <i>mutually comparable</i> using the specified comparator.
686 >     *         not <i>mutually comparable</i> using the specified comparator.
687       * @throws NoSuchElementException if the collection is empty.
688       * @see Comparable
689       */
# Line 677 | Line 691 | public class Collections {
691          if (comp==null)
692              return (T)max((Collection<SelfComparable>) (Collection) coll);
693  
694 <        Iterator<? extends T> i = coll.iterator();
695 <        T candidate = i.next();
694 >        Iterator<? extends T> i = coll.iterator();
695 >        T candidate = i.next();
696  
697          while (i.hasNext()) {
698 <            T next = i.next();
699 <            if (comp.compare(next, candidate) > 0)
700 <                candidate = next;
701 <        }
702 <        return candidate;
698 >            T next = i.next();
699 >            if (comp.compare(next, candidate) > 0)
700 >                candidate = next;
701 >        }
702 >        return candidate;
703      }
704  
705      /**
# Line 745 | Line 759 | public class Collections {
759       */
760      public static void rotate(List<?> list, int distance) {
761          if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD)
762 <            rotate1((List)list, distance);
762 >            rotate1(list, distance);
763          else
764 <            rotate2((List)list, distance);
764 >            rotate2(list, distance);
765      }
766  
767      private static <T> void rotate1(List<T> list, int distance) {
# Line 977 | Line 991 | public class Collections {
991       * is serializable.
992       *
993       * @param  c the collection for which an unmodifiable view is to be
994 <     *         returned.
994 >     *         returned.
995       * @return an unmodifiable view of the specified collection.
996       */
997      public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
998 <        return new UnmodifiableCollection<T>(c);
998 >        return new UnmodifiableCollection<T>(c);
999      }
1000  
1001      /**
1002       * @serial include
1003       */
1004      static class UnmodifiableCollection<E> implements Collection<E>, Serializable {
1005 <        // use serialVersionUID from JDK 1.2.2 for interoperability
992 <        private static final long serialVersionUID = 1820017752578914078L;
1005 >        private static final long serialVersionUID = 1820017752578914078L;
1006  
1007 <        final Collection<? extends E> c;
1007 >        final Collection<? extends E> c;
1008  
1009 <        UnmodifiableCollection(Collection<? extends E> c) {
1009 >        UnmodifiableCollection(Collection<? extends E> c) {
1010              if (c==null)
1011                  throw new NullPointerException();
1012              this.c = c;
1013          }
1014  
1015 <        public int size()                   {return c.size();}
1016 <        public boolean isEmpty()            {return c.isEmpty();}
1017 <        public boolean contains(Object o)   {return c.contains(o);}
1018 <        public Object[] toArray()           {return c.toArray();}
1019 <        public <T> T[] toArray(T[] a)       {return c.toArray(a);}
1015 >        public int size()                   {return c.size();}
1016 >        public boolean isEmpty()            {return c.isEmpty();}
1017 >        public boolean contains(Object o)   {return c.contains(o);}
1018 >        public Object[] toArray()           {return c.toArray();}
1019 >        public <T> T[] toArray(T[] a)       {return c.toArray(a);}
1020          public String toString()            {return c.toString();}
1021  
1022 <        public Iterator<E> iterator() {
1023 <            return new Iterator<E>() {
1024 <                Iterator<? extends E> i = c.iterator();
1025 <
1026 <                public boolean hasNext() {return i.hasNext();}
1027 <                public E next()          {return i.next();}
1028 <                public void remove() {
1029 <                    throw new UnsupportedOperationException();
1022 >        public Iterator<E> iterator() {
1023 >            return new Iterator<E>() {
1024 >                private final Iterator<? extends E> i = c.iterator();
1025 >
1026 >                public boolean hasNext() {return i.hasNext();}
1027 >                public E next()          {return i.next();}
1028 >                public void remove() {
1029 >                    throw new UnsupportedOperationException();
1030                  }
1031 <            };
1031 >            };
1032          }
1033  
1034 <        public boolean add(E e){
1035 <            throw new UnsupportedOperationException();
1034 >        public boolean add(E e) {
1035 >            throw new UnsupportedOperationException();
1036          }
1037 <        public boolean remove(Object o) {
1038 <            throw new UnsupportedOperationException();
1037 >        public boolean remove(Object o) {
1038 >            throw new UnsupportedOperationException();
1039          }
1040  
1041 <        public boolean containsAll(Collection<?> coll) {
1042 <            return c.containsAll(coll);
1041 >        public boolean containsAll(Collection<?> coll) {
1042 >            return c.containsAll(coll);
1043          }
1044 <        public boolean addAll(Collection<? extends E> coll) {
1045 <            throw new UnsupportedOperationException();
1044 >        public boolean addAll(Collection<? extends E> coll) {
1045 >            throw new UnsupportedOperationException();
1046          }
1047 <        public boolean removeAll(Collection<?> coll) {
1048 <            throw new UnsupportedOperationException();
1047 >        public boolean removeAll(Collection<?> coll) {
1048 >            throw new UnsupportedOperationException();
1049          }
1050 <        public boolean retainAll(Collection<?> coll) {
1051 <            throw new UnsupportedOperationException();
1050 >        public boolean retainAll(Collection<?> coll) {
1051 >            throw new UnsupportedOperationException();
1052          }
1053 <        public void clear() {
1054 <            throw new UnsupportedOperationException();
1053 >        public void clear() {
1054 >            throw new UnsupportedOperationException();
1055          }
1056      }
1057  
# Line 1056 | Line 1069 | public class Collections {
1069       * @return an unmodifiable view of the specified set.
1070       */
1071      public static <T> Set<T> unmodifiableSet(Set<? extends T> s) {
1072 <        return new UnmodifiableSet<T>(s);
1072 >        return new UnmodifiableSet<T>(s);
1073      }
1074  
1075      /**
1076       * @serial include
1077       */
1078      static class UnmodifiableSet<E> extends UnmodifiableCollection<E>
1079 <                                 implements Set<E>, Serializable {
1080 <        private static final long serialVersionUID = -9215047833775013803L;
1079 >                                 implements Set<E>, Serializable {
1080 >        private static final long serialVersionUID = -9215047833775013803L;
1081  
1082 <        UnmodifiableSet(Set<? extends E> s)     {super(s);}
1083 <        public boolean equals(Object o) {return c.equals(o);}
1084 <        public int hashCode()           {return c.hashCode();}
1082 >        UnmodifiableSet(Set<? extends E> s)     {super(s);}
1083 >        public boolean equals(Object o) {return o == this || c.equals(o);}
1084 >        public int hashCode()           {return c.hashCode();}
1085      }
1086  
1087      /**
# Line 1088 | Line 1101 | public class Collections {
1101       * @return an unmodifiable view of the specified sorted set.
1102       */
1103      public static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s) {
1104 <        return new UnmodifiableSortedSet<T>(s);
1104 >        return new UnmodifiableSortedSet<T>(s);
1105      }
1106  
1107      /**
1108       * @serial include
1109       */
1110      static class UnmodifiableSortedSet<E>
1111 <                             extends UnmodifiableSet<E>
1112 <                             implements SortedSet<E>, Serializable {
1113 <        private static final long serialVersionUID = -4929149591599911165L;
1111 >                             extends UnmodifiableSet<E>
1112 >                             implements SortedSet<E>, Serializable {
1113 >        private static final long serialVersionUID = -4929149591599911165L;
1114          private final SortedSet<E> ss;
1115  
1116 <        UnmodifiableSortedSet(SortedSet<E> s) {super(s); ss = s;}
1116 >        UnmodifiableSortedSet(SortedSet<E> s) {super(s); ss = s;}
1117  
1118          public Comparator<? super E> comparator() {return ss.comparator();}
1119  
# Line 1114 | Line 1127 | public class Collections {
1127              return new UnmodifiableSortedSet<E>(ss.tailSet(fromElement));
1128          }
1129  
1130 <        public E first()                   {return ss.first();}
1131 <        public E last()                    {return ss.last();}
1130 >        public E first()                   {return ss.first();}
1131 >        public E last()                    {return ss.last();}
1132      }
1133  
1134      /**
# Line 1134 | Line 1147 | public class Collections {
1147       * @return an unmodifiable view of the specified list.
1148       */
1149      public static <T> List<T> unmodifiableList(List<? extends T> list) {
1150 <        return (list instanceof RandomAccess ?
1150 >        return (list instanceof RandomAccess ?
1151                  new UnmodifiableRandomAccessList<T>(list) :
1152                  new UnmodifiableList<T>(list));
1153      }
# Line 1143 | Line 1156 | public class Collections {
1156       * @serial include
1157       */
1158      static class UnmodifiableList<E> extends UnmodifiableCollection<E>
1159 <                                  implements List<E> {
1160 <        static final long serialVersionUID = -283967356065247728L;
1161 <        final List<? extends E> list;
1162 <
1163 <        UnmodifiableList(List<? extends E> list) {
1164 <            super(list);
1165 <            this.list = list;
1166 <        }
1154 <
1155 <        public boolean equals(Object o) {return list.equals(o);}
1156 <        public int hashCode()           {return list.hashCode();}
1157 <
1158 <        public E get(int index) {return list.get(index);}
1159 <        public E set(int index, E element) {
1160 <            throw new UnsupportedOperationException();
1161 <        }
1162 <        public void add(int index, E element) {
1163 <            throw new UnsupportedOperationException();
1164 <        }
1165 <        public E remove(int index) {
1166 <            throw new UnsupportedOperationException();
1167 <        }
1168 <        public int indexOf(Object o)            {return list.indexOf(o);}
1169 <        public int lastIndexOf(Object o)        {return list.lastIndexOf(o);}
1170 <        public boolean addAll(int index, Collection<? extends E> c) {
1171 <            throw new UnsupportedOperationException();
1172 <        }
1173 <        public ListIterator<E> listIterator()   {return listIterator(0);}
1174 <
1175 <        public ListIterator<E> listIterator(final int index) {
1176 <            return new ListIterator<E>() {
1177 <                ListIterator<? extends E> i = list.listIterator(index);
1178 <
1179 <                public boolean hasNext()     {return i.hasNext();}
1180 <                public E next()              {return i.next();}
1181 <                public boolean hasPrevious() {return i.hasPrevious();}
1182 <                public E previous()          {return i.previous();}
1183 <                public int nextIndex()       {return i.nextIndex();}
1184 <                public int previousIndex()   {return i.previousIndex();}
1159 >                                  implements List<E> {
1160 >        private static final long serialVersionUID = -283967356065247728L;
1161 >        final List<? extends E> list;
1162 >
1163 >        UnmodifiableList(List<? extends E> list) {
1164 >            super(list);
1165 >            this.list = list;
1166 >        }
1167  
1168 <                public void remove() {
1169 <                    throw new UnsupportedOperationException();
1168 >        public boolean equals(Object o) {return o == this || list.equals(o);}
1169 >        public int hashCode()           {return list.hashCode();}
1170 >
1171 >        public E get(int index) {return list.get(index);}
1172 >        public E set(int index, E element) {
1173 >            throw new UnsupportedOperationException();
1174 >        }
1175 >        public void add(int index, E element) {
1176 >            throw new UnsupportedOperationException();
1177 >        }
1178 >        public E remove(int index) {
1179 >            throw new UnsupportedOperationException();
1180 >        }
1181 >        public int indexOf(Object o)            {return list.indexOf(o);}
1182 >        public int lastIndexOf(Object o)        {return list.lastIndexOf(o);}
1183 >        public boolean addAll(int index, Collection<? extends E> c) {
1184 >            throw new UnsupportedOperationException();
1185 >        }
1186 >        public ListIterator<E> listIterator()   {return listIterator(0);}
1187 >
1188 >        public ListIterator<E> listIterator(final int index) {
1189 >            return new ListIterator<E>() {
1190 >                private final ListIterator<? extends E> i
1191 >                    = list.listIterator(index);
1192 >
1193 >                public boolean hasNext()     {return i.hasNext();}
1194 >                public E next()              {return i.next();}
1195 >                public boolean hasPrevious() {return i.hasPrevious();}
1196 >                public E previous()          {return i.previous();}
1197 >                public int nextIndex()       {return i.nextIndex();}
1198 >                public int previousIndex()   {return i.previousIndex();}
1199 >
1200 >                public void remove() {
1201 >                    throw new UnsupportedOperationException();
1202                  }
1203 <                public void set(E e) {
1204 <                    throw new UnsupportedOperationException();
1203 >                public void set(E e) {
1204 >                    throw new UnsupportedOperationException();
1205                  }
1206 <                public void add(E e) {
1207 <                    throw new UnsupportedOperationException();
1206 >                public void add(E e) {
1207 >                    throw new UnsupportedOperationException();
1208                  }
1209 <            };
1210 <        }
1209 >            };
1210 >        }
1211  
1212 <        public List<E> subList(int fromIndex, int toIndex) {
1212 >        public List<E> subList(int fromIndex, int toIndex) {
1213              return new UnmodifiableList<E>(list.subList(fromIndex, toIndex));
1214          }
1215  
# Line 1213 | Line 1227 | public class Collections {
1227           */
1228          private Object readResolve() {
1229              return (list instanceof RandomAccess
1230 <                    ? new UnmodifiableRandomAccessList<E>(list)
1231 <                    : this);
1230 >                    ? new UnmodifiableRandomAccessList<E>(list)
1231 >                    : this);
1232          }
1233      }
1234  
# Line 1228 | Line 1242 | public class Collections {
1242              super(list);
1243          }
1244  
1245 <        public List<E> subList(int fromIndex, int toIndex) {
1245 >        public List<E> subList(int fromIndex, int toIndex) {
1246              return new UnmodifiableRandomAccessList<E>(
1247                  list.subList(fromIndex, toIndex));
1248          }
# Line 1261 | Line 1275 | public class Collections {
1275       * @return an unmodifiable view of the specified map.
1276       */
1277      public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> m) {
1278 <        return new UnmodifiableMap<K,V>(m);
1278 >        return new UnmodifiableMap<K,V>(m);
1279      }
1280  
1281      /**
1282       * @serial include
1283       */
1284      private static class UnmodifiableMap<K,V> implements Map<K,V>, Serializable {
1285 <        // use serialVersionUID from JDK 1.2.2 for interoperability
1272 <        private static final long serialVersionUID = -1034234728574286014L;
1285 >        private static final long serialVersionUID = -1034234728574286014L;
1286  
1287 <        private final Map<? extends K, ? extends V> m;
1287 >        private final Map<? extends K, ? extends V> m;
1288  
1289 <        UnmodifiableMap(Map<? extends K, ? extends V> m) {
1289 >        UnmodifiableMap(Map<? extends K, ? extends V> m) {
1290              if (m==null)
1291                  throw new NullPointerException();
1292              this.m = m;
1293          }
1294  
1295 <        public int size()                        {return m.size();}
1296 <        public boolean isEmpty()                 {return m.isEmpty();}
1297 <        public boolean containsKey(Object key)   {return m.containsKey(key);}
1298 <        public boolean containsValue(Object val) {return m.containsValue(val);}
1299 <        public V get(Object key)                 {return m.get(key);}
1300 <
1301 <        public V put(K key, V value) {
1302 <            throw new UnsupportedOperationException();
1303 <        }
1304 <        public V remove(Object key) {
1305 <            throw new UnsupportedOperationException();
1306 <        }
1307 <        public void putAll(Map<? extends K, ? extends V> m) {
1308 <            throw new UnsupportedOperationException();
1309 <        }
1310 <        public void clear() {
1311 <            throw new UnsupportedOperationException();
1312 <        }
1313 <
1314 <        private transient Set<K> keySet = null;
1315 <        private transient Set<Map.Entry<K,V>> entrySet = null;
1316 <        private transient Collection<V> values = null;
1317 <
1318 <        public Set<K> keySet() {
1319 <            if (keySet==null)
1320 <                keySet = unmodifiableSet(m.keySet());
1321 <            return keySet;
1322 <        }
1323 <
1324 <        public Set<Map.Entry<K,V>> entrySet() {
1325 <            if (entrySet==null)
1326 <                entrySet = new UnmodifiableEntrySet<K,V>(m.entrySet());
1327 <            return entrySet;
1328 <        }
1329 <
1330 <        public Collection<V> values() {
1331 <            if (values==null)
1332 <                values = unmodifiableCollection(m.values());
1333 <            return values;
1334 <        }
1295 >        public int size()                        {return m.size();}
1296 >        public boolean isEmpty()                 {return m.isEmpty();}
1297 >        public boolean containsKey(Object key)   {return m.containsKey(key);}
1298 >        public boolean containsValue(Object val) {return m.containsValue(val);}
1299 >        public V get(Object key)                 {return m.get(key);}
1300 >
1301 >        public V put(K key, V value) {
1302 >            throw new UnsupportedOperationException();
1303 >        }
1304 >        public V remove(Object key) {
1305 >            throw new UnsupportedOperationException();
1306 >        }
1307 >        public void putAll(Map<? extends K, ? extends V> m) {
1308 >            throw new UnsupportedOperationException();
1309 >        }
1310 >        public void clear() {
1311 >            throw new UnsupportedOperationException();
1312 >        }
1313 >
1314 >        private transient Set<K> keySet = null;
1315 >        private transient Set<Map.Entry<K,V>> entrySet = null;
1316 >        private transient Collection<V> values = null;
1317 >
1318 >        public Set<K> keySet() {
1319 >            if (keySet==null)
1320 >                keySet = unmodifiableSet(m.keySet());
1321 >            return keySet;
1322 >        }
1323 >
1324 >        public Set<Map.Entry<K,V>> entrySet() {
1325 >            if (entrySet==null)
1326 >                entrySet = new UnmodifiableEntrySet<K,V>(m.entrySet());
1327 >            return entrySet;
1328 >        }
1329 >
1330 >        public Collection<V> values() {
1331 >            if (values==null)
1332 >                values = unmodifiableCollection(m.values());
1333 >            return values;
1334 >        }
1335  
1336 <        public boolean equals(Object o) {return m.equals(o);}
1337 <        public int hashCode()           {return m.hashCode();}
1336 >        public boolean equals(Object o) {return o == this || m.equals(o);}
1337 >        public int hashCode()           {return m.hashCode();}
1338          public String toString()        {return m.toString();}
1339  
1340          /**
# Line 1333 | Line 1346 | public class Collections {
1346           * @serial include
1347           */
1348          static class UnmodifiableEntrySet<K,V>
1349 <            extends UnmodifiableSet<Map.Entry<K,V>> {
1350 <            private static final long serialVersionUID = 7854390611657943733L;
1349 >            extends UnmodifiableSet<Map.Entry<K,V>> {
1350 >            private static final long serialVersionUID = 7854390611657943733L;
1351  
1352              UnmodifiableEntrySet(Set<? extends Map.Entry<? extends K, ? extends V>> s) {
1353                  super((Set)s);
1354              }
1355              public Iterator<Map.Entry<K,V>> iterator() {
1356                  return new Iterator<Map.Entry<K,V>>() {
1357 <                    Iterator<? extends Map.Entry<? extends K, ? extends V>> i = c.iterator();
1357 >                    private final Iterator<? extends Map.Entry<? extends K, ? extends V>> i = c.iterator();
1358  
1359                      public boolean hasNext() {
1360                          return i.hasNext();
1361                      }
1362 <                    public Map.Entry<K,V> next() {
1363 <                        return new UnmodifiableEntry<K,V>(i.next());
1362 >                    public Map.Entry<K,V> next() {
1363 >                        return new UnmodifiableEntry<K,V>(i.next());
1364                      }
1365                      public void remove() {
1366                          throw new UnsupportedOperationException();
# Line 1366 | Line 1379 | public class Collections {
1379                  // We don't pass a to c.toArray, to avoid window of
1380                  // vulnerability wherein an unscrupulous multithreaded client
1381                  // could get his hands on raw (unwrapped) Entries from c.
1382 <                Object[] arr = c.toArray(a.length==0 ? a : Arrays.copyOf(a, 0));
1382 >                Object[] arr = c.toArray(a.length==0 ? a : Arrays.copyOf(a, 0));
1383  
1384                  for (int i=0; i<arr.length; i++)
1385                      arr[i] = new UnmodifiableEntry<K,V>((Map.Entry<K,V>)arr[i]);
# Line 1389 | Line 1402 | public class Collections {
1402              public boolean contains(Object o) {
1403                  if (!(o instanceof Map.Entry))
1404                      return false;
1405 <                return c.contains(new UnmodifiableEntry<K,V>((Map.Entry<K,V>) o));
1405 >                return c.contains(
1406 >                    new UnmodifiableEntry<Object,Object>((Map.Entry<?,?>) o));
1407              }
1408  
1409              /**
# Line 1428 | Line 1442 | public class Collections {
1442  
1443                  UnmodifiableEntry(Map.Entry<? extends K, ? extends V> e) {this.e = e;}
1444  
1445 <                public K getKey()         {return e.getKey();}
1445 >                public K getKey()         {return e.getKey();}
1446                  public V getValue()  {return e.getValue();}
1447                  public V setValue(V value) {
1448                      throw new UnsupportedOperationException();
1449                  }
1450 <                public int hashCode()     {return e.hashCode();}
1450 >                public int hashCode()     {return e.hashCode();}
1451                  public boolean equals(Object o) {
1452                      if (!(o instanceof Map.Entry))
1453                          return false;
# Line 1463 | Line 1477 | public class Collections {
1477       * @return an unmodifiable view of the specified sorted map.
1478       */
1479      public static <K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K, ? extends V> m) {
1480 <        return new UnmodifiableSortedMap<K,V>(m);
1480 >        return new UnmodifiableSortedMap<K,V>(m);
1481      }
1482  
1483      /**
1484       * @serial include
1485       */
1486      static class UnmodifiableSortedMap<K,V>
1487 <          extends UnmodifiableMap<K,V>
1488 <          implements SortedMap<K,V>, Serializable {
1489 <        private static final long serialVersionUID = -8806743815996713206L;
1487 >          extends UnmodifiableMap<K,V>
1488 >          implements SortedMap<K,V>, Serializable {
1489 >        private static final long serialVersionUID = -8806743815996713206L;
1490  
1491          private final SortedMap<K, ? extends V> sm;
1492  
1493 <        UnmodifiableSortedMap(SortedMap<K, ? extends V> m) {super(m); sm = m;}
1493 >        UnmodifiableSortedMap(SortedMap<K, ? extends V> m) {super(m); sm = m;}
1494  
1495          public Comparator<? super K> comparator() {return sm.comparator();}
1496  
# Line 1529 | Line 1543 | public class Collections {
1543       * @return a synchronized view of the specified collection.
1544       */
1545      public static <T> Collection<T> synchronizedCollection(Collection<T> c) {
1546 <        return new SynchronizedCollection<T>(c);
1546 >        return new SynchronizedCollection<T>(c);
1547      }
1548  
1549      static <T> Collection<T> synchronizedCollection(Collection<T> c, Object mutex) {
1550 <        return new SynchronizedCollection<T>(c, mutex);
1550 >        return new SynchronizedCollection<T>(c, mutex);
1551      }
1552  
1553      /**
1554       * @serial include
1555       */
1556      static class SynchronizedCollection<E> implements Collection<E>, Serializable {
1557 <        // use serialVersionUID from JDK 1.2.2 for interoperability
1544 <        private static final long serialVersionUID = 3053995032091335093L;
1557 >        private static final long serialVersionUID = 3053995032091335093L;
1558  
1559 <        final Collection<E> c;     // Backing Collection
1560 <        final Object       mutex;  // Object on which to synchronize
1559 >        final Collection<E> c;  // Backing Collection
1560 >        final Object mutex;     // Object on which to synchronize
1561  
1562 <        SynchronizedCollection(Collection<E> c) {
1562 >        SynchronizedCollection(Collection<E> c) {
1563              if (c==null)
1564                  throw new NullPointerException();
1565 <            this.c = c;
1565 >            this.c = c;
1566              mutex = this;
1567          }
1568 <        SynchronizedCollection(Collection<E> c, Object mutex) {
1569 <            this.c = c;
1568 >        SynchronizedCollection(Collection<E> c, Object mutex) {
1569 >            this.c = c;
1570              this.mutex = mutex;
1571          }
1572  
1573 <        public int size() {
1574 <            synchronized(mutex) {return c.size();}
1573 >        public int size() {
1574 >            synchronized(mutex) {return c.size();}
1575          }
1576 <        public boolean isEmpty() {
1577 <            synchronized(mutex) {return c.isEmpty();}
1576 >        public boolean isEmpty() {
1577 >            synchronized(mutex) {return c.isEmpty();}
1578          }
1579 <        public boolean contains(Object o) {
1580 <            synchronized(mutex) {return c.contains(o);}
1579 >        public boolean contains(Object o) {
1580 >            synchronized(mutex) {return c.contains(o);}
1581          }
1582 <        public Object[] toArray() {
1583 <            synchronized(mutex) {return c.toArray();}
1582 >        public Object[] toArray() {
1583 >            synchronized(mutex) {return c.toArray();}
1584          }
1585 <        public <T> T[] toArray(T[] a) {
1586 <            synchronized(mutex) {return c.toArray(a);}
1585 >        public <T> T[] toArray(T[] a) {
1586 >            synchronized(mutex) {return c.toArray(a);}
1587          }
1588  
1589 <        public Iterator<E> iterator() {
1589 >        public Iterator<E> iterator() {
1590              return c.iterator(); // Must be manually synched by user!
1591          }
1592  
1593 <        public boolean add(E e) {
1594 <            synchronized(mutex) {return c.add(e);}
1593 >        public boolean add(E e) {
1594 >            synchronized(mutex) {return c.add(e);}
1595          }
1596 <        public boolean remove(Object o) {
1597 <            synchronized(mutex) {return c.remove(o);}
1596 >        public boolean remove(Object o) {
1597 >            synchronized(mutex) {return c.remove(o);}
1598          }
1599  
1600 <        public boolean containsAll(Collection<?> coll) {
1601 <            synchronized(mutex) {return c.containsAll(coll);}
1600 >        public boolean containsAll(Collection<?> coll) {
1601 >            synchronized(mutex) {return c.containsAll(coll);}
1602          }
1603 <        public boolean addAll(Collection<? extends E> coll) {
1604 <            synchronized(mutex) {return c.addAll(coll);}
1603 >        public boolean addAll(Collection<? extends E> coll) {
1604 >            synchronized(mutex) {return c.addAll(coll);}
1605          }
1606 <        public boolean removeAll(Collection<?> coll) {
1607 <            synchronized(mutex) {return c.removeAll(coll);}
1606 >        public boolean removeAll(Collection<?> coll) {
1607 >            synchronized(mutex) {return c.removeAll(coll);}
1608          }
1609 <        public boolean retainAll(Collection<?> coll) {
1610 <            synchronized(mutex) {return c.retainAll(coll);}
1609 >        public boolean retainAll(Collection<?> coll) {
1610 >            synchronized(mutex) {return c.retainAll(coll);}
1611          }
1612 <        public void clear() {
1613 <            synchronized(mutex) {c.clear();}
1612 >        public void clear() {
1613 >            synchronized(mutex) {c.clear();}
1614          }
1615 <        public String toString() {
1616 <            synchronized(mutex) {return c.toString();}
1615 >        public String toString() {
1616 >            synchronized(mutex) {return c.toString();}
1617          }
1618          private void writeObject(ObjectOutputStream s) throws IOException {
1619 <            synchronized(mutex) {s.defaultWriteObject();}
1619 >            synchronized(mutex) {s.defaultWriteObject();}
1620          }
1621      }
1622  
# Line 1633 | Line 1646 | public class Collections {
1646       * @return a synchronized view of the specified set.
1647       */
1648      public static <T> Set<T> synchronizedSet(Set<T> s) {
1649 <        return new SynchronizedSet<T>(s);
1649 >        return new SynchronizedSet<T>(s);
1650      }
1651  
1652      static <T> Set<T> synchronizedSet(Set<T> s, Object mutex) {
1653 <        return new SynchronizedSet<T>(s, mutex);
1653 >        return new SynchronizedSet<T>(s, mutex);
1654      }
1655  
1656      /**
1657       * @serial include
1658       */
1659      static class SynchronizedSet<E>
1660 <          extends SynchronizedCollection<E>
1661 <          implements Set<E> {
1662 <        private static final long serialVersionUID = 487447009682186044L;
1660 >          extends SynchronizedCollection<E>
1661 >          implements Set<E> {
1662 >        private static final long serialVersionUID = 487447009682186044L;
1663  
1664 <        SynchronizedSet(Set<E> s) {
1664 >        SynchronizedSet(Set<E> s) {
1665              super(s);
1666          }
1667 <        SynchronizedSet(Set<E> s, Object mutex) {
1667 >        SynchronizedSet(Set<E> s, Object mutex) {
1668              super(s, mutex);
1669          }
1670  
1671 <        public boolean equals(Object o) {
1672 <            synchronized(mutex) {return c.equals(o);}
1671 >        public boolean equals(Object o) {
1672 >            synchronized(mutex) {return c.equals(o);}
1673          }
1674 <        public int hashCode() {
1675 <            synchronized(mutex) {return c.hashCode();}
1674 >        public int hashCode() {
1675 >            synchronized(mutex) {return c.hashCode();}
1676          }
1677      }
1678  
# Line 1701 | Line 1714 | public class Collections {
1714       * @return a synchronized view of the specified sorted set.
1715       */
1716      public static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s) {
1717 <        return new SynchronizedSortedSet<T>(s);
1717 >        return new SynchronizedSortedSet<T>(s);
1718      }
1719  
1720      /**
1721       * @serial include
1722       */
1723      static class SynchronizedSortedSet<E>
1724 <        extends SynchronizedSet<E>
1725 <        implements SortedSet<E>
1724 >        extends SynchronizedSet<E>
1725 >        implements SortedSet<E>
1726      {
1727 <        private static final long serialVersionUID = 8695801310862127406L;
1727 >        private static final long serialVersionUID = 8695801310862127406L;
1728  
1729          final private SortedSet<E> ss;
1730  
1731 <        SynchronizedSortedSet(SortedSet<E> s) {
1731 >        SynchronizedSortedSet(SortedSet<E> s) {
1732              super(s);
1733              ss = s;
1734          }
1735 <        SynchronizedSortedSet(SortedSet<E> s, Object mutex) {
1735 >        SynchronizedSortedSet(SortedSet<E> s, Object mutex) {
1736              super(s, mutex);
1737              ss = s;
1738          }
1739  
1740 <        public Comparator<? super E> comparator() {
1741 <            synchronized(mutex) {return ss.comparator();}
1740 >        public Comparator<? super E> comparator() {
1741 >            synchronized(mutex) {return ss.comparator();}
1742          }
1743  
1744          public SortedSet<E> subSet(E fromElement, E toElement) {
1745 <            synchronized(mutex) {
1745 >            synchronized(mutex) {
1746                  return new SynchronizedSortedSet<E>(
1747                      ss.subSet(fromElement, toElement), mutex);
1748              }
1749          }
1750          public SortedSet<E> headSet(E toElement) {
1751 <            synchronized(mutex) {
1751 >            synchronized(mutex) {
1752                  return new SynchronizedSortedSet<E>(ss.headSet(toElement), mutex);
1753              }
1754          }
1755          public SortedSet<E> tailSet(E fromElement) {
1756 <            synchronized(mutex) {
1756 >            synchronized(mutex) {
1757                 return new SynchronizedSortedSet<E>(ss.tailSet(fromElement),mutex);
1758              }
1759          }
1760  
1761          public E first() {
1762 <            synchronized(mutex) {return ss.first();}
1762 >            synchronized(mutex) {return ss.first();}
1763          }
1764          public E last() {
1765 <            synchronized(mutex) {return ss.last();}
1765 >            synchronized(mutex) {return ss.last();}
1766          }
1767      }
1768  
# Line 1779 | Line 1792 | public class Collections {
1792       * @return a synchronized view of the specified list.
1793       */
1794      public static <T> List<T> synchronizedList(List<T> list) {
1795 <        return (list instanceof RandomAccess ?
1795 >        return (list instanceof RandomAccess ?
1796                  new SynchronizedRandomAccessList<T>(list) :
1797                  new SynchronizedList<T>(list));
1798      }
1799  
1800      static <T> List<T> synchronizedList(List<T> list, Object mutex) {
1801 <        return (list instanceof RandomAccess ?
1801 >        return (list instanceof RandomAccess ?
1802                  new SynchronizedRandomAccessList<T>(list, mutex) :
1803                  new SynchronizedList<T>(list, mutex));
1804      }
# Line 1794 | Line 1807 | public class Collections {
1807       * @serial include
1808       */
1809      static class SynchronizedList<E>
1810 <        extends SynchronizedCollection<E>
1811 <        implements List<E> {
1812 <        static final long serialVersionUID = -7754090372962971524L;
1813 <
1814 <        final List<E> list;
1815 <
1816 <        SynchronizedList(List<E> list) {
1817 <            super(list);
1818 <            this.list = list;
1819 <        }
1820 <        SynchronizedList(List<E> list, Object mutex) {
1810 >        extends SynchronizedCollection<E>
1811 >        implements List<E> {
1812 >        private static final long serialVersionUID = -7754090372962971524L;
1813 >
1814 >        final List<E> list;
1815 >
1816 >        SynchronizedList(List<E> list) {
1817 >            super(list);
1818 >            this.list = list;
1819 >        }
1820 >        SynchronizedList(List<E> list, Object mutex) {
1821              super(list, mutex);
1822 <            this.list = list;
1822 >            this.list = list;
1823          }
1824  
1825 <        public boolean equals(Object o) {
1826 <            synchronized(mutex) {return list.equals(o);}
1825 >        public boolean equals(Object o) {
1826 >            synchronized(mutex) {return list.equals(o);}
1827          }
1828 <        public int hashCode() {
1829 <            synchronized(mutex) {return list.hashCode();}
1828 >        public int hashCode() {
1829 >            synchronized(mutex) {return list.hashCode();}
1830          }
1831  
1832 <        public E get(int index) {
1833 <            synchronized(mutex) {return list.get(index);}
1832 >        public E get(int index) {
1833 >            synchronized(mutex) {return list.get(index);}
1834          }
1835 <        public E set(int index, E element) {
1836 <            synchronized(mutex) {return list.set(index, element);}
1835 >        public E set(int index, E element) {
1836 >            synchronized(mutex) {return list.set(index, element);}
1837          }
1838 <        public void add(int index, E element) {
1839 <            synchronized(mutex) {list.add(index, element);}
1838 >        public void add(int index, E element) {
1839 >            synchronized(mutex) {list.add(index, element);}
1840          }
1841 <        public E remove(int index) {
1842 <            synchronized(mutex) {return list.remove(index);}
1841 >        public E remove(int index) {
1842 >            synchronized(mutex) {return list.remove(index);}
1843          }
1844  
1845 <        public int indexOf(Object o) {
1846 <            synchronized(mutex) {return list.indexOf(o);}
1845 >        public int indexOf(Object o) {
1846 >            synchronized(mutex) {return list.indexOf(o);}
1847          }
1848 <        public int lastIndexOf(Object o) {
1849 <            synchronized(mutex) {return list.lastIndexOf(o);}
1848 >        public int lastIndexOf(Object o) {
1849 >            synchronized(mutex) {return list.lastIndexOf(o);}
1850          }
1851  
1852 <        public boolean addAll(int index, Collection<? extends E> c) {
1853 <            synchronized(mutex) {return list.addAll(index, c);}
1852 >        public boolean addAll(int index, Collection<? extends E> c) {
1853 >            synchronized(mutex) {return list.addAll(index, c);}
1854          }
1855  
1856 <        public ListIterator<E> listIterator() {
1857 <            return list.listIterator(); // Must be manually synched by user
1856 >        public ListIterator<E> listIterator() {
1857 >            return list.listIterator(); // Must be manually synched by user
1858          }
1859  
1860 <        public ListIterator<E> listIterator(int index) {
1861 <            return list.listIterator(index); // Must be manually synched by user
1860 >        public ListIterator<E> listIterator(int index) {
1861 >            return list.listIterator(index); // Must be manually synched by user
1862          }
1863  
1864 <        public List<E> subList(int fromIndex, int toIndex) {
1865 <            synchronized(mutex) {
1864 >        public List<E> subList(int fromIndex, int toIndex) {
1865 >            synchronized(mutex) {
1866                  return new SynchronizedList<E>(list.subList(fromIndex, toIndex),
1867                                              mutex);
1868              }
# Line 1869 | Line 1882 | public class Collections {
1882           */
1883          private Object readResolve() {
1884              return (list instanceof RandomAccess
1885 <                    ? new SynchronizedRandomAccessList<E>(list)
1886 <                    : this);
1885 >                    ? new SynchronizedRandomAccessList<E>(list)
1886 >                    : this);
1887          }
1888      }
1889  
# Line 1878 | Line 1891 | public class Collections {
1891       * @serial include
1892       */
1893      static class SynchronizedRandomAccessList<E>
1894 <        extends SynchronizedList<E>
1895 <        implements RandomAccess {
1894 >        extends SynchronizedList<E>
1895 >        implements RandomAccess {
1896  
1897          SynchronizedRandomAccessList(List<E> list) {
1898              super(list);
1899          }
1900  
1901 <        SynchronizedRandomAccessList(List<E> list, Object mutex) {
1901 >        SynchronizedRandomAccessList(List<E> list, Object mutex) {
1902              super(list, mutex);
1903          }
1904  
1905 <        public List<E> subList(int fromIndex, int toIndex) {
1906 <            synchronized(mutex) {
1905 >        public List<E> subList(int fromIndex, int toIndex) {
1906 >            synchronized(mutex) {
1907                  return new SynchronizedRandomAccessList<E>(
1908                      list.subList(fromIndex, toIndex), mutex);
1909              }
1910          }
1911  
1912 <        static final long serialVersionUID = 1530674583602358482L;
1912 >        private static final long serialVersionUID = 1530674583602358482L;
1913  
1914          /**
1915           * Allows instances to be deserialized in pre-1.4 JREs (which do
# Line 1937 | Line 1950 | public class Collections {
1950       * @return a synchronized view of the specified map.
1951       */
1952      public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
1953 <        return new SynchronizedMap<K,V>(m);
1953 >        return new SynchronizedMap<K,V>(m);
1954      }
1955  
1956      /**
1957       * @serial include
1958       */
1959      private static class SynchronizedMap<K,V>
1960 <        implements Map<K,V>, Serializable {
1961 <        // use serialVersionUID from JDK 1.2.2 for interoperability
1949 <        private static final long serialVersionUID = 1978198479659022715L;
1960 >        implements Map<K,V>, Serializable {
1961 >        private static final long serialVersionUID = 1978198479659022715L;
1962  
1963 <        private final Map<K,V> m;     // Backing Map
1964 <        final Object      mutex;        // Object on which to synchronize
1963 >        private final Map<K,V> m;     // Backing Map
1964 >        final Object      mutex;        // Object on which to synchronize
1965  
1966 <        SynchronizedMap(Map<K,V> m) {
1966 >        SynchronizedMap(Map<K,V> m) {
1967              if (m==null)
1968                  throw new NullPointerException();
1969              this.m = m;
1970              mutex = this;
1971          }
1972  
1973 <        SynchronizedMap(Map<K,V> m, Object mutex) {
1973 >        SynchronizedMap(Map<K,V> m, Object mutex) {
1974              this.m = m;
1975              this.mutex = mutex;
1976          }
1977  
1978 <        public int size() {
1979 <            synchronized(mutex) {return m.size();}
1978 >        public int size() {
1979 >            synchronized(mutex) {return m.size();}
1980          }
1981 <        public boolean isEmpty(){
1982 <            synchronized(mutex) {return m.isEmpty();}
1981 >        public boolean isEmpty() {
1982 >            synchronized(mutex) {return m.isEmpty();}
1983          }
1984 <        public boolean containsKey(Object key) {
1985 <            synchronized(mutex) {return m.containsKey(key);}
1984 >        public boolean containsKey(Object key) {
1985 >            synchronized(mutex) {return m.containsKey(key);}
1986          }
1987 <        public boolean containsValue(Object value){
1988 <            synchronized(mutex) {return m.containsValue(value);}
1987 >        public boolean containsValue(Object value) {
1988 >            synchronized(mutex) {return m.containsValue(value);}
1989          }
1990 <        public V get(Object key) {
1991 <            synchronized(mutex) {return m.get(key);}
1990 >        public V get(Object key) {
1991 >            synchronized(mutex) {return m.get(key);}
1992          }
1993  
1994 <        public V put(K key, V value) {
1995 <            synchronized(mutex) {return m.put(key, value);}
1994 >        public V put(K key, V value) {
1995 >            synchronized(mutex) {return m.put(key, value);}
1996          }
1997 <        public V remove(Object key) {
1998 <            synchronized(mutex) {return m.remove(key);}
1997 >        public V remove(Object key) {
1998 >            synchronized(mutex) {return m.remove(key);}
1999          }
2000 <        public void putAll(Map<? extends K, ? extends V> map) {
2001 <            synchronized(mutex) {m.putAll(map);}
2000 >        public void putAll(Map<? extends K, ? extends V> map) {
2001 >            synchronized(mutex) {m.putAll(map);}
2002 >        }
2003 >        public void clear() {
2004 >            synchronized(mutex) {m.clear();}
2005          }
1991        public void clear() {
1992            synchronized(mutex) {m.clear();}
1993        }
2006  
2007 <        private transient Set<K> keySet = null;
2008 <        private transient Set<Map.Entry<K,V>> entrySet = null;
2009 <        private transient Collection<V> values = null;
2007 >        private transient Set<K> keySet = null;
2008 >        private transient Set<Map.Entry<K,V>> entrySet = null;
2009 >        private transient Collection<V> values = null;
2010  
2011 <        public Set<K> keySet() {
2011 >        public Set<K> keySet() {
2012              synchronized(mutex) {
2013                  if (keySet==null)
2014                      keySet = new SynchronizedSet<K>(m.keySet(), mutex);
2015                  return keySet;
2016              }
2017 <        }
2017 >        }
2018  
2019 <        public Set<Map.Entry<K,V>> entrySet() {
2019 >        public Set<Map.Entry<K,V>> entrySet() {
2020              synchronized(mutex) {
2021                  if (entrySet==null)
2022                      entrySet = new SynchronizedSet<Map.Entry<K,V>>(m.entrySet(), mutex);
2023                  return entrySet;
2024              }
2025 <        }
2025 >        }
2026  
2027 <        public Collection<V> values() {
2027 >        public Collection<V> values() {
2028              synchronized(mutex) {
2029                  if (values==null)
2030                      values = new SynchronizedCollection<V>(m.values(), mutex);
# Line 2020 | Line 2032 | public class Collections {
2032              }
2033          }
2034  
2035 <        public boolean equals(Object o) {
2035 >        public boolean equals(Object o) {
2036              synchronized(mutex) {return m.equals(o);}
2037          }
2038 <        public int hashCode() {
2038 >        public int hashCode() {
2039              synchronized(mutex) {return m.hashCode();}
2040          }
2041 <        public String toString() {
2042 <            synchronized(mutex) {return m.toString();}
2041 >        public String toString() {
2042 >            synchronized(mutex) {return m.toString();}
2043          }
2044          private void writeObject(ObjectOutputStream s) throws IOException {
2045 <            synchronized(mutex) {s.defaultWriteObject();}
2045 >            synchronized(mutex) {s.defaultWriteObject();}
2046          }
2047      }
2048  
# Line 2077 | Line 2089 | public class Collections {
2089       * @return a synchronized view of the specified sorted map.
2090       */
2091      public static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m) {
2092 <        return new SynchronizedSortedMap<K,V>(m);
2092 >        return new SynchronizedSortedMap<K,V>(m);
2093      }
2094  
2095  
# Line 2085 | Line 2097 | public class Collections {
2097       * @serial include
2098       */
2099      static class SynchronizedSortedMap<K,V>
2100 <        extends SynchronizedMap<K,V>
2101 <        implements SortedMap<K,V>
2100 >        extends SynchronizedMap<K,V>
2101 >        implements SortedMap<K,V>
2102      {
2103 <        private static final long serialVersionUID = -8798146769416483793L;
2103 >        private static final long serialVersionUID = -8798146769416483793L;
2104  
2105          private final SortedMap<K,V> sm;
2106  
2107 <        SynchronizedSortedMap(SortedMap<K,V> m) {
2107 >        SynchronizedSortedMap(SortedMap<K,V> m) {
2108              super(m);
2109              sm = m;
2110          }
2111 <        SynchronizedSortedMap(SortedMap<K,V> m, Object mutex) {
2111 >        SynchronizedSortedMap(SortedMap<K,V> m, Object mutex) {
2112              super(m, mutex);
2113              sm = m;
2114          }
2115  
2116 <        public Comparator<? super K> comparator() {
2117 <            synchronized(mutex) {return sm.comparator();}
2116 >        public Comparator<? super K> comparator() {
2117 >            synchronized(mutex) {return sm.comparator();}
2118          }
2119  
2120          public SortedMap<K,V> subMap(K fromKey, K toKey) {
2121 <            synchronized(mutex) {
2121 >            synchronized(mutex) {
2122                  return new SynchronizedSortedMap<K,V>(
2123                      sm.subMap(fromKey, toKey), mutex);
2124              }
2125          }
2126          public SortedMap<K,V> headMap(K toKey) {
2127 <            synchronized(mutex) {
2127 >            synchronized(mutex) {
2128                  return new SynchronizedSortedMap<K,V>(sm.headMap(toKey), mutex);
2129              }
2130          }
2131          public SortedMap<K,V> tailMap(K fromKey) {
2132 <            synchronized(mutex) {
2132 >            synchronized(mutex) {
2133                 return new SynchronizedSortedMap<K,V>(sm.tailMap(fromKey),mutex);
2134              }
2135          }
2136  
2137          public K firstKey() {
2138 <            synchronized(mutex) {return sm.firstKey();}
2138 >            synchronized(mutex) {return sm.firstKey();}
2139          }
2140          public K lastKey() {
2141 <            synchronized(mutex) {return sm.lastKey();}
2141 >            synchronized(mutex) {return sm.lastKey();}
2142          }
2143      }
2144  
2145      // Dynamically typesafe collection wrappers
2146  
2147      /**
2148 <     * Returns a dynamically typesafe view of the specified collection.  Any
2149 <     * attempt to insert an element of the wrong type will result in an
2150 <     * immediate <tt>ClassCastException</tt>.  Assuming a collection contains
2151 <     * no incorrectly typed elements prior to the time a dynamically typesafe
2152 <     * view is generated, and that all subsequent access to the collection
2153 <     * takes place through the view, it is <i>guaranteed</i> that the
2154 <     * collection cannot contain an incorrectly typed element.
2148 >     * Returns a dynamically typesafe view of the specified collection.
2149 >     * Any attempt to insert an element of the wrong type will result in an
2150 >     * immediate {@link ClassCastException}.  Assuming a collection
2151 >     * contains no incorrectly typed elements prior to the time a
2152 >     * dynamically typesafe view is generated, and that all subsequent
2153 >     * access to the collection takes place through the view, it is
2154 >     * <i>guaranteed</i> that the collection cannot contain an incorrectly
2155 >     * typed element.
2156       *
2157       * <p>The generics mechanism in the language provides compile-time
2158       * (static) type checking, but it is possible to defeat this mechanism
# Line 2151 | Line 2164 | public class Collections {
2164       * inserting an element of the wrong type.
2165       *
2166       * <p>Another use of dynamically typesafe views is debugging.  Suppose a
2167 <     * program fails with a <tt>ClassCastException</tt>, indicating that an
2167 >     * program fails with a {@code ClassCastException}, indicating that an
2168       * incorrectly typed element was put into a parameterized collection.
2169       * Unfortunately, the exception can occur at any time after the erroneous
2170       * element is inserted, so it typically provides little or no information
# Line 2159 | Line 2172 | public class Collections {
2172       * one can quickly determine its source by temporarily modifying the
2173       * program to wrap the collection with a dynamically typesafe view.
2174       * For example, this declaration:
2175 <     * <pre>
2176 <     *     Collection&lt;String&gt; c = new HashSet&lt;String&gt;();
2177 <     * </pre>
2175 >     *  <pre> {@code
2176 >     *     Collection<String> c = new HashSet<String>();
2177 >     * }</pre>
2178       * may be replaced temporarily by this one:
2179 <     * <pre>
2180 <     *     Collection&lt;String&gt; c = Collections.checkedCollection(
2181 <     *         new HashSet&lt;String&gt;(), String.class);
2182 <     * </pre>
2179 >     *  <pre> {@code
2180 >     *     Collection<String> c = Collections.checkedCollection(
2181 >     *         new HashSet<String>(), String.class);
2182 >     * }</pre>
2183       * Running the program again will cause it to fail at the point where
2184       * an incorrectly typed element is inserted into the collection, clearly
2185       * identifying the source of the problem.  Once the problem is fixed, the
# Line 2174 | Line 2187 | public class Collections {
2187       *
2188       * <p>The returned collection does <i>not</i> pass the hashCode and equals
2189       * operations through to the backing collection, but relies on
2190 <     * <tt>Object</tt>'s <tt>equals</tt> and <tt>hashCode</tt> methods.  This
2190 >     * {@code Object}'s {@code equals} and {@code hashCode} methods.  This
2191       * is necessary to preserve the contracts of these operations in the case
2192       * that the backing collection is a set or a list.
2193       *
2194       * <p>The returned collection will be serializable if the specified
2195       * collection is serializable.
2196       *
2197 +     * <p>Since {@code null} is considered to be a value of any reference
2198 +     * type, the returned collection permits insertion of null elements
2199 +     * whenever the backing collection does.
2200 +     *
2201       * @param c the collection for which a dynamically typesafe view is to be
2202 <     *             returned
2203 <     * @param type the type of element that <tt>c</tt> is permitted to hold
2202 >     *          returned
2203 >     * @param type the type of element that {@code c} is permitted to hold
2204       * @return a dynamically typesafe view of the specified collection
2205       * @since 1.5
2206       */
# Line 2192 | Line 2209 | public class Collections {
2209          return new CheckedCollection<E>(c, type);
2210      }
2211  
2212 +    @SuppressWarnings("unchecked")
2213 +    static <T> T[] zeroLengthArray(Class<T> type) {
2214 +        return (T[]) Array.newInstance(type, 0);
2215 +    }
2216 +
2217      /**
2218       * @serial include
2219       */
# Line 2202 | Line 2224 | public class Collections {
2224          final Class<E> type;
2225  
2226          void typeCheck(Object o) {
2227 <            if (!type.isInstance(o))
2228 <                throw new ClassCastException("Attempt to insert " +
2229 <                   o.getClass() + " element into collection with element type "
2230 <                   + type);
2227 >            if (o != null && !type.isInstance(o))
2228 >                throw new ClassCastException(badElementMsg(o));
2229 >        }
2230 >
2231 >        private String badElementMsg(Object o) {
2232 >            return "Attempt to insert " + o.getClass() +
2233 >                " element into collection with element type " + type;
2234          }
2235  
2236          CheckedCollection(Collection<E> c, Class<E> type) {
# Line 2215 | Line 2240 | public class Collections {
2240              this.type = type;
2241          }
2242  
2243 <        public int size()                   { return c.size(); }
2244 <        public boolean isEmpty()            { return c.isEmpty(); }
2245 <        public boolean contains(Object o)   { return c.contains(o); }
2246 <        public Object[] toArray()           { return c.toArray(); }
2247 <        public <T> T[] toArray(T[] a)       { return c.toArray(a); }
2248 <        public String toString()            { return c.toString(); }
2249 <        public boolean remove(Object o)     { return c.remove(o); }
2243 >        public int size()                 { return c.size(); }
2244 >        public boolean isEmpty()          { return c.isEmpty(); }
2245 >        public boolean contains(Object o) { return c.contains(o); }
2246 >        public Object[] toArray()         { return c.toArray(); }
2247 >        public <T> T[] toArray(T[] a)     { return c.toArray(a); }
2248 >        public String toString()          { return c.toString(); }
2249 >        public boolean remove(Object o)   { return c.remove(o); }
2250 >        public void clear()               {        c.clear(); }
2251 >
2252          public boolean containsAll(Collection<?> coll) {
2253              return c.containsAll(coll);
2254          }
# Line 2231 | Line 2258 | public class Collections {
2258          public boolean retainAll(Collection<?> coll) {
2259              return c.retainAll(coll);
2260          }
2234        public void clear() {
2235            c.clear();
2236        }
2261  
2262          public Iterator<E> iterator() {
2263 <            return new Iterator<E>() {
2264 <                private final Iterator<E> it = c.iterator();
2265 <                public boolean hasNext() { return it.hasNext(); }
2266 <                public E next()          { return it.next(); }
2267 <                public void remove()     {        it.remove(); }};
2268 <        }
2263 >            final Iterator<E> it = c.iterator();
2264 >            return new Iterator<E>() {
2265 >                public boolean hasNext() { return it.hasNext(); }
2266 >                public E next()          { return it.next(); }
2267 >                public void remove()     {        it.remove(); }};
2268 >        }
2269  
2270 <        public boolean add(E e){
2270 >        public boolean add(E e) {
2271              typeCheck(e);
2272              return c.add(e);
2273          }
2274  
2275 <        public boolean addAll(Collection<? extends E> coll) {
2252 <            /*
2253 <             * Dump coll into an array of the required type.  This serves
2254 <             * three purposes: it insulates us from concurrent changes in
2255 <             * the contents of coll, it type-checks all of the elements in
2256 <             * coll, and it provides all-or-nothing semantics (which we
2257 <             * wouldn't get if we type-checked each element as we added it).
2258 <             */
2259 <            E[] a = null;
2260 <            try {
2261 <                a = coll.toArray(zeroLengthElementArray());
2262 <            } catch (ArrayStoreException e) {
2263 <                throw new ClassCastException();
2264 <            }
2275 >        private E[] zeroLengthElementArray = null; // Lazily initialized
2276  
2277 <            boolean result = false;
2278 <            for (E e : a)
2279 <                result |= c.add(e);
2269 <            return result;
2277 >        private E[] zeroLengthElementArray() {
2278 >            return zeroLengthElementArray != null ? zeroLengthElementArray :
2279 >                (zeroLengthElementArray = zeroLengthArray(type));
2280          }
2281  
2282 <        private E[] zeroLengthElementArray = null; // Lazily initialized
2282 >        @SuppressWarnings("unchecked")
2283 >        Collection<E> checkedCopyOf(Collection<? extends E> coll) {
2284 >            Object[] a = null;
2285 >            try {
2286 >                E[] z = zeroLengthElementArray();
2287 >                a = coll.toArray(z);
2288 >                // Defend against coll violating the toArray contract
2289 >                if (a.getClass() != z.getClass())
2290 >                    a = Arrays.copyOf(a, a.length, z.getClass());
2291 >            } catch (ArrayStoreException ignore) {
2292 >                // To get better and consistent diagnostics,
2293 >                // we call typeCheck explicitly on each element.
2294 >                // We call clone() to defend against coll retaining a
2295 >                // reference to the returned array and storing a bad
2296 >                // element into it after it has been type checked.
2297 >                a = coll.toArray().clone();
2298 >                for (Object o : a)
2299 >                    typeCheck(o);
2300 >            }
2301 >            // A slight abuse of the type system, but safe here.
2302 >            return (Collection<E>) Arrays.asList(a);
2303 >        }
2304  
2305 <        /*
2306 <         * We don't need locking or volatile, because it's OK if we create
2307 <         * several zeroLengthElementArrays, and they're immutable.
2308 <         */
2309 <        E[] zeroLengthElementArray() {
2310 <            if (zeroLengthElementArray == null)
2280 <                zeroLengthElementArray = (E[]) Array.newInstance(type, 0);
2281 <            return zeroLengthElementArray;
2305 >        public boolean addAll(Collection<? extends E> coll) {
2306 >            // Doing things this way insulates us from concurrent changes
2307 >            // in the contents of coll and provides all-or-nothing
2308 >            // semantics (which we wouldn't get if we type-checked each
2309 >            // element as we added it)
2310 >            return c.addAll(checkedCopyOf(coll));
2311          }
2312      }
2313  
2314      /**
2315       * Returns a dynamically typesafe view of the specified set.
2316       * Any attempt to insert an element of the wrong type will result in
2317 <     * an immediate <tt>ClassCastException</tt>.  Assuming a set contains
2317 >     * an immediate {@link ClassCastException}.  Assuming a set contains
2318       * no incorrectly typed elements prior to the time a dynamically typesafe
2319       * view is generated, and that all subsequent access to the set
2320       * takes place through the view, it is <i>guaranteed</i> that the
2321       * set cannot contain an incorrectly typed element.
2322       *
2323       * <p>A discussion of the use of dynamically typesafe views may be
2324 <     * found in the documentation for the {@link #checkedCollection checkedCollection}
2325 <     * method.
2324 >     * found in the documentation for the {@link #checkedCollection
2325 >     * checkedCollection} method.
2326       *
2327       * <p>The returned set will be serializable if the specified set is
2328       * serializable.
2329       *
2330 +     * <p>Since {@code null} is considered to be a value of any reference
2331 +     * type, the returned set permits insertion of null elements whenever
2332 +     * the backing set does.
2333 +     *
2334       * @param s the set for which a dynamically typesafe view is to be
2335 <     *             returned
2336 <     * @param type the type of element that <tt>s</tt> is permitted to hold
2335 >     *          returned
2336 >     * @param type the type of element that {@code s} is permitted to hold
2337       * @return a dynamically typesafe view of the specified set
2338       * @since 1.5
2339       */
# Line 2318 | Line 2351 | public class Collections {
2351  
2352          CheckedSet(Set<E> s, Class<E> elementType) { super(s, elementType); }
2353  
2354 <        public boolean equals(Object o) { return c.equals(o); }
2354 >        public boolean equals(Object o) { return o == this || c.equals(o); }
2355          public int hashCode()           { return c.hashCode(); }
2356      }
2357  
2358      /**
2359 <     * Returns a dynamically typesafe view of the specified sorted set.  Any
2360 <     * attempt to insert an element of the wrong type will result in an
2361 <     * immediate <tt>ClassCastException</tt>.  Assuming a sorted set contains
2362 <     * no incorrectly typed elements prior to the time a dynamically typesafe
2363 <     * view is generated, and that all subsequent access to the sorted set
2364 <     * takes place through the view, it is <i>guaranteed</i> that the sorted
2365 <     * set cannot contain an incorrectly typed element.
2359 >     * Returns a dynamically typesafe view of the specified sorted set.
2360 >     * Any attempt to insert an element of the wrong type will result in an
2361 >     * immediate {@link ClassCastException}.  Assuming a sorted set
2362 >     * contains no incorrectly typed elements prior to the time a
2363 >     * dynamically typesafe view is generated, and that all subsequent
2364 >     * access to the sorted set takes place through the view, it is
2365 >     * <i>guaranteed</i> that the sorted set cannot contain an incorrectly
2366 >     * typed element.
2367       *
2368       * <p>A discussion of the use of dynamically typesafe views may be
2369 <     * found in the documentation for the {@link #checkedCollection checkedCollection}
2370 <     * method.
2369 >     * found in the documentation for the {@link #checkedCollection
2370 >     * checkedCollection} method.
2371       *
2372       * <p>The returned sorted set will be serializable if the specified sorted
2373       * set is serializable.
2374       *
2375 +     * <p>Since {@code null} is considered to be a value of any reference
2376 +     * type, the returned sorted set permits insertion of null elements
2377 +     * whenever the backing sorted set does.
2378 +     *
2379       * @param s the sorted set for which a dynamically typesafe view is to be
2380 <     *             returned
2381 <     * @param type the type of element that <tt>s</tt> is permitted to hold
2380 >     *          returned
2381 >     * @param type the type of element that {@code s} is permitted to hold
2382       * @return a dynamically typesafe view of the specified sorted set
2383       * @since 1.5
2384       */
# Line 2368 | Line 2406 | public class Collections {
2406          public E last()                    { return ss.last(); }
2407  
2408          public SortedSet<E> subSet(E fromElement, E toElement) {
2409 <            return new CheckedSortedSet<E>(ss.subSet(fromElement,toElement),
2372 <                                           type);
2409 >            return checkedSortedSet(ss.subSet(fromElement,toElement), type);
2410          }
2411          public SortedSet<E> headSet(E toElement) {
2412 <            return new CheckedSortedSet<E>(ss.headSet(toElement), type);
2412 >            return checkedSortedSet(ss.headSet(toElement), type);
2413          }
2414          public SortedSet<E> tailSet(E fromElement) {
2415 <            return new CheckedSortedSet<E>(ss.tailSet(fromElement), type);
2415 >            return checkedSortedSet(ss.tailSet(fromElement), type);
2416          }
2417      }
2418  
2419      /**
2420       * Returns a dynamically typesafe view of the specified list.
2421       * Any attempt to insert an element of the wrong type will result in
2422 <     * an immediate <tt>ClassCastException</tt>.  Assuming a list contains
2422 >     * an immediate {@link ClassCastException}.  Assuming a list contains
2423       * no incorrectly typed elements prior to the time a dynamically typesafe
2424       * view is generated, and that all subsequent access to the list
2425       * takes place through the view, it is <i>guaranteed</i> that the
2426       * list cannot contain an incorrectly typed element.
2427       *
2428       * <p>A discussion of the use of dynamically typesafe views may be
2429 <     * found in the documentation for the {@link #checkedCollection checkedCollection}
2430 <     * method.
2429 >     * found in the documentation for the {@link #checkedCollection
2430 >     * checkedCollection} method.
2431       *
2432 <     * <p>The returned list will be serializable if the specified list is
2433 <     * serializable.
2432 >     * <p>The returned list will be serializable if the specified list
2433 >     * is serializable.
2434 >     *
2435 >     * <p>Since {@code null} is considered to be a value of any reference
2436 >     * type, the returned list permits insertion of null elements whenever
2437 >     * the backing list does.
2438       *
2439       * @param list the list for which a dynamically typesafe view is to be
2440       *             returned
2441 <     * @param type the type of element that <tt>list</tt> is permitted to hold
2441 >     * @param type the type of element that {@code list} is permitted to hold
2442       * @return a dynamically typesafe view of the specified list
2443       * @since 1.5
2444       */
# Line 2410 | Line 2451 | public class Collections {
2451      /**
2452       * @serial include
2453       */
2454 <    static class CheckedList<E> extends CheckedCollection<E>
2455 <                                implements List<E>
2454 >    static class CheckedList<E>
2455 >        extends CheckedCollection<E>
2456 >        implements List<E>
2457      {
2458 <        static final long serialVersionUID = 65247728283967356L;
2458 >        private static final long serialVersionUID = 65247728283967356L;
2459          final List<E> list;
2460  
2461          CheckedList(List<E> list, Class<E> type) {
# Line 2421 | Line 2463 | public class Collections {
2463              this.list = list;
2464          }
2465  
2466 <        public boolean equals(Object o)  { return list.equals(o); }
2466 >        public boolean equals(Object o)  { return o == this || list.equals(o); }
2467          public int hashCode()            { return list.hashCode(); }
2468          public E get(int index)          { return list.get(index); }
2469          public E remove(int index)       { return list.remove(index); }
# Line 2439 | Line 2481 | public class Collections {
2481          }
2482  
2483          public boolean addAll(int index, Collection<? extends E> c) {
2484 <            // See CheckCollection.addAll, above, for an explanation
2443 <            E[] a = null;
2444 <            try {
2445 <                a = c.toArray(zeroLengthElementArray());
2446 <            } catch (ArrayStoreException e) {
2447 <                throw new ClassCastException();
2448 <            }
2449 <
2450 <            return list.addAll(index, Arrays.asList(a));
2484 >            return list.addAll(index, checkedCopyOf(c));
2485          }
2486          public ListIterator<E> listIterator()   { return listIterator(0); }
2487  
2488          public ListIterator<E> listIterator(final int index) {
2489 <            return new ListIterator<E>() {
2456 <                ListIterator<E> i = list.listIterator(index);
2489 >            final ListIterator<E> i = list.listIterator(index);
2490  
2491 +            return new ListIterator<E>() {
2492                  public boolean hasNext()     { return i.hasNext(); }
2493                  public E next()              { return i.next(); }
2494                  public boolean hasPrevious() { return i.hasPrevious(); }
2495                  public E previous()          { return i.previous(); }
2496                  public int nextIndex()       { return i.nextIndex(); }
2497                  public int previousIndex()   { return i.previousIndex(); }
2498 <                public void remove()         { i.remove(); }
2498 >                public void remove()         {        i.remove(); }
2499  
2500                  public void set(E e) {
2501                      typeCheck(e);
# Line 2499 | Line 2533 | public class Collections {
2533      }
2534  
2535      /**
2536 <     * Returns a dynamically typesafe view of the specified map.  Any attempt
2537 <     * to insert a mapping whose key or value have the wrong type will result
2538 <     * in an immediate <tt>ClassCastException</tt>.  Similarly, any attempt to
2539 <     * modify the value currently associated with a key will result in an
2540 <     * immediate <tt>ClassCastException</tt>, whether the modification is
2541 <     * attempted directly through the map itself, or through a {@link
2542 <     * Map.Entry} instance obtained from the map's {@link Map#entrySet()
2543 <     * entry set} view.
2536 >     * Returns a dynamically typesafe view of the specified map.
2537 >     * Any attempt to insert a mapping whose key or value have the wrong
2538 >     * type will result in an immediate {@link ClassCastException}.
2539 >     * Similarly, any attempt to modify the value currently associated with
2540 >     * a key will result in an immediate {@link ClassCastException},
2541 >     * whether the modification is attempted directly through the map
2542 >     * itself, or through a {@link Map.Entry} instance obtained from the
2543 >     * map's {@link Map#entrySet() entry set} view.
2544       *
2545       * <p>Assuming a map contains no incorrectly typed keys or values
2546       * prior to the time a dynamically typesafe view is generated, and
# Line 2515 | Line 2549 | public class Collections {
2549       * map cannot contain an incorrectly typed key or value.
2550       *
2551       * <p>A discussion of the use of dynamically typesafe views may be
2552 <     * found in the documentation for the {@link #checkedCollection checkedCollection}
2553 <     * method.
2552 >     * found in the documentation for the {@link #checkedCollection
2553 >     * checkedCollection} method.
2554       *
2555       * <p>The returned map will be serializable if the specified map is
2556       * serializable.
2557       *
2558 +     * <p>Since {@code null} is considered to be a value of any reference
2559 +     * type, the returned map permits insertion of null keys or values
2560 +     * whenever the backing map does.
2561 +     *
2562       * @param m the map for which a dynamically typesafe view is to be
2563 <     *             returned
2564 <     * @param keyType the type of key that <tt>m</tt> is permitted to hold
2565 <     * @param valueType the type of value that <tt>m</tt> is permitted to hold
2563 >     *          returned
2564 >     * @param keyType the type of key that {@code m} is permitted to hold
2565 >     * @param valueType the type of value that {@code m} is permitted to hold
2566       * @return a dynamically typesafe view of the specified map
2567       * @since 1.5
2568       */
2569 <    public static <K, V> Map<K, V> checkedMap(Map<K, V> m, Class<K> keyType,
2569 >    public static <K, V> Map<K, V> checkedMap(Map<K, V> m,
2570 >                                              Class<K> keyType,
2571                                                Class<V> valueType) {
2572          return new CheckedMap<K,V>(m, keyType, valueType);
2573      }
# Line 2537 | Line 2576 | public class Collections {
2576      /**
2577       * @serial include
2578       */
2579 <    private static class CheckedMap<K,V> implements Map<K,V>,
2580 <                                                         Serializable
2579 >    private static class CheckedMap<K,V>
2580 >        implements Map<K,V>, Serializable
2581      {
2582          private static final long serialVersionUID = 5742860141034234728L;
2583  
# Line 2547 | Line 2586 | public class Collections {
2586          final Class<V> valueType;
2587  
2588          private void typeCheck(Object key, Object value) {
2589 <            if (!keyType.isInstance(key))
2590 <                throw new ClassCastException("Attempt to insert " +
2591 <                    key.getClass() + " key into collection with key type "
2592 <                    + keyType);
2593 <
2594 <            if (!valueType.isInstance(value))
2595 <                throw new ClassCastException("Attempt to insert " +
2596 <                    value.getClass() +" value into collection with value type "
2597 <                    + valueType);
2589 >            if (key != null && !keyType.isInstance(key))
2590 >                throw new ClassCastException(badKeyMsg(key));
2591 >
2592 >            if (value != null && !valueType.isInstance(value))
2593 >                throw new ClassCastException(badValueMsg(value));
2594 >        }
2595 >
2596 >        private String badKeyMsg(Object key) {
2597 >            return "Attempt to insert " + key.getClass() +
2598 >                " key into map with key type " + keyType;
2599 >        }
2600 >
2601 >        private String badValueMsg(Object value) {
2602 >            return "Attempt to insert " + value.getClass() +
2603 >                " value into map with value type " + valueType;
2604          }
2605  
2606          CheckedMap(Map<K, V> m, Class<K> keyType, Class<V> valueType) {
# Line 2575 | Line 2620 | public class Collections {
2620          public void clear()                    { m.clear(); }
2621          public Set<K> keySet()                 { return m.keySet(); }
2622          public Collection<V> values()          { return m.values(); }
2623 <        public boolean equals(Object o)        { return m.equals(o);  }
2623 >        public boolean equals(Object o)        { return o == this || m.equals(o); }
2624          public int hashCode()                  { return m.hashCode(); }
2625          public String toString()               { return m.toString(); }
2626  
# Line 2584 | Line 2629 | public class Collections {
2629              return m.put(key, value);
2630          }
2631  
2632 +        @SuppressWarnings("unchecked")
2633          public void putAll(Map<? extends K, ? extends V> t) {
2634 <            // See CheckCollection.addAll, above, for an explanation
2635 <            K[] keys = null;
2636 <            try {
2637 <                keys = t.keySet().toArray(zeroLengthKeyArray());
2638 <            } catch (ArrayStoreException e) {
2639 <                throw new ClassCastException();
2640 <            }
2641 <            V[] values = null;
2642 <            try {
2643 <                values = t.values().toArray(zeroLengthValueArray());
2644 <            } catch (ArrayStoreException e) {
2645 <                throw new ClassCastException();
2634 >            // Satisfy the following goals:
2635 >            // - good diagnostics in case of type mismatch
2636 >            // - all-or-nothing semantics
2637 >            // - protection from malicious t
2638 >            // - correct behavior if t is a concurrent map
2639 >            Object[] entries = t.entrySet().toArray();
2640 >            List<Map.Entry<K,V>> checked =
2641 >                new ArrayList<Map.Entry<K,V>>(entries.length);
2642 >            for (Object o : entries) {
2643 >                Map.Entry<?,?> e = (Map.Entry<?,?>) o;
2644 >                Object k = e.getKey();
2645 >                Object v = e.getValue();
2646 >                typeCheck(k, v);
2647 >                checked.add(
2648 >                    new AbstractMap.SimpleImmutableEntry<K,V>((K) k, (V) v));
2649              }
2650 <
2651 <            if (keys.length != values.length)
2603 <                throw new ConcurrentModificationException();
2604 <
2605 <            for (int i = 0; i < keys.length; i++)
2606 <                m.put(keys[i], values[i]);
2607 <        }
2608 <
2609 <        // Lazily initialized
2610 <        private K[] zeroLengthKeyArray   = null;
2611 <        private V[] zeroLengthValueArray = null;
2612 <
2613 <        /*
2614 <         * We don't need locking or volatile, because it's OK if we create
2615 <         * several zeroLengthValueArrays, and they're immutable.
2616 <         */
2617 <        private K[] zeroLengthKeyArray() {
2618 <            if (zeroLengthKeyArray == null)
2619 <                zeroLengthKeyArray = (K[]) Array.newInstance(keyType, 0);
2620 <            return zeroLengthKeyArray;
2621 <        }
2622 <        private V[] zeroLengthValueArray() {
2623 <            if (zeroLengthValueArray == null)
2624 <                zeroLengthValueArray = (V[]) Array.newInstance(valueType, 0);
2625 <            return zeroLengthValueArray;
2650 >            for (Map.Entry<K,V> e : checked)
2651 >                m.put(e.getKey(), e.getValue());
2652          }
2653  
2654          private transient Set<Map.Entry<K,V>> entrySet = null;
# Line 2642 | Line 2668 | public class Collections {
2668           * @serial exclude
2669           */
2670          static class CheckedEntrySet<K,V> implements Set<Map.Entry<K,V>> {
2671 <            Set<Map.Entry<K,V>> s;
2672 <            Class<V> valueType;
2671 >            private final Set<Map.Entry<K,V>> s;
2672 >            private final Class<V> valueType;
2673  
2674              CheckedEntrySet(Set<Map.Entry<K, V>> s, Class<V> valueType) {
2675                  this.s = s;
2676                  this.valueType = valueType;
2677              }
2678  
2679 <            public int size()                   { return s.size(); }
2680 <            public boolean isEmpty()            { return s.isEmpty(); }
2681 <            public String toString()            { return s.toString(); }
2682 <            public int hashCode()               { return s.hashCode(); }
2683 <            public boolean remove(Object o)     { return s.remove(o); }
2658 <            public boolean removeAll(Collection<?> coll) {
2659 <                return s.removeAll(coll);
2660 <            }
2661 <            public boolean retainAll(Collection<?> coll) {
2662 <                return s.retainAll(coll);
2663 <            }
2664 <            public void clear() {
2665 <                s.clear();
2666 <            }
2679 >            public int size()        { return s.size(); }
2680 >            public boolean isEmpty() { return s.isEmpty(); }
2681 >            public String toString() { return s.toString(); }
2682 >            public int hashCode()    { return s.hashCode(); }
2683 >            public void clear()      {        s.clear(); }
2684  
2685 <            public boolean add(Map.Entry<K, V> e){
2685 >            public boolean add(Map.Entry<K, V> e) {
2686                  throw new UnsupportedOperationException();
2687              }
2688              public boolean addAll(Collection<? extends Map.Entry<K, V>> coll) {
2689                  throw new UnsupportedOperationException();
2690              }
2691  
2675
2692              public Iterator<Map.Entry<K,V>> iterator() {
2693 <                return new Iterator<Map.Entry<K,V>>() {
2694 <                    Iterator<Map.Entry<K, V>> i = s.iterator();
2693 >                final Iterator<Map.Entry<K, V>> i = s.iterator();
2694 >                final Class<V> valueType = this.valueType;
2695  
2696 +                return new Iterator<Map.Entry<K,V>>() {
2697                      public boolean hasNext() { return i.hasNext(); }
2698                      public void remove()     { i.remove(); }
2699  
2700                      public Map.Entry<K,V> next() {
2701 <                        return new CheckedEntry<K,V>(i.next(), valueType);
2701 >                        return checkedEntry(i.next(), valueType);
2702                      }
2703                  };
2704              }
2705  
2706 +            @SuppressWarnings("unchecked")
2707              public Object[] toArray() {
2708                  Object[] source = s.toArray();
2709  
# Line 2698 | Line 2716 | public class Collections {
2716                                   new Object[source.length]);
2717  
2718                  for (int i = 0; i < source.length; i++)
2719 <                    dest[i] = new CheckedEntry<K,V>((Map.Entry<K,V>)source[i],
2720 <                                                    valueType);
2719 >                    dest[i] = checkedEntry((Map.Entry<K,V>)source[i],
2720 >                                           valueType);
2721                  return dest;
2722              }
2723  
2724 +            @SuppressWarnings("unchecked")
2725              public <T> T[] toArray(T[] a) {
2726                  // We don't pass a to s.toArray, to avoid window of
2727                  // vulnerability wherein an unscrupulous multithreaded client
2728                  // could get his hands on raw (unwrapped) Entries from s.
2729 <                Object[] arr = s.toArray(a.length==0 ? a : Arrays.copyOf(a, 0));
2729 >                T[] arr = s.toArray(a.length==0 ? a : Arrays.copyOf(a, 0));
2730  
2731                  for (int i=0; i<arr.length; i++)
2732 <                    arr[i] = new CheckedEntry<K,V>((Map.Entry<K,V>)arr[i],
2733 <                                                   valueType);
2732 >                    arr[i] = (T) checkedEntry((Map.Entry<K,V>)arr[i],
2733 >                                              valueType);
2734                  if (arr.length > a.length)
2735 <                    return (T[])arr;
2735 >                    return arr;
2736  
2737                  System.arraycopy(arr, 0, a, 0, arr.length);
2738                  if (a.length > arr.length)
# Line 2730 | Line 2749 | public class Collections {
2749              public boolean contains(Object o) {
2750                  if (!(o instanceof Map.Entry))
2751                      return false;
2752 +                Map.Entry<?,?> e = (Map.Entry<?,?>) o;
2753                  return s.contains(
2754 <                    new CheckedEntry<K,V>((Map.Entry<K,V>) o, valueType));
2754 >                    (e instanceof CheckedEntry) ? e : checkedEntry(e, valueType));
2755              }
2756  
2757              /**
2758 <             * The next two methods are overridden to protect against
2759 <             * an unscrupulous collection whose contains(Object o) method
2760 <             * senses when o is a Map.Entry, and calls o.setValue.
2758 >             * The bulk collection methods are overridden to protect
2759 >             * against an unscrupulous collection whose contains(Object o)
2760 >             * method senses when o is a Map.Entry, and calls o.setValue.
2761               */
2762 <            public boolean containsAll(Collection<?> coll) {
2763 <                Iterator<?> e = coll.iterator();
2764 <                while (e.hasNext())
2745 <                    if (!contains(e.next())) // Invokes safe contains() above
2762 >            public boolean containsAll(Collection<?> c) {
2763 >                for (Object o : c)
2764 >                    if (!contains(o)) // Invokes safe contains() above
2765                          return false;
2766                  return true;
2767              }
2768  
2769 +            public boolean remove(Object o) {
2770 +                if (!(o instanceof Map.Entry))
2771 +                    return false;
2772 +                return s.remove(new AbstractMap.SimpleImmutableEntry
2773 +                                <Object, Object>((Map.Entry<?,?>)o));
2774 +            }
2775 +
2776 +            public boolean removeAll(Collection<?> c) {
2777 +                return batchRemove(c, false);
2778 +            }
2779 +            public boolean retainAll(Collection<?> c) {
2780 +                return batchRemove(c, true);
2781 +            }
2782 +            private boolean batchRemove(Collection<?> c, boolean complement) {
2783 +                boolean modified = false;
2784 +                Iterator<Map.Entry<K,V>> it = iterator();
2785 +                while (it.hasNext()) {
2786 +                    if (c.contains(it.next()) != complement) {
2787 +                        it.remove();
2788 +                        modified = true;
2789 +                    }
2790 +                }
2791 +                return modified;
2792 +            }
2793 +
2794              public boolean equals(Object o) {
2795                  if (o == this)
2796                      return true;
2797                  if (!(o instanceof Set))
2798                      return false;
2799                  Set<?> that = (Set<?>) o;
2800 <                if (that.size() != s.size())
2801 <                    return false;
2802 <                return containsAll(that); // Invokes safe containsAll() above
2800 >                return that.size() == s.size()
2801 >                    && containsAll(that); // Invokes safe containsAll() above
2802 >            }
2803 >
2804 >            static <K,V,T> CheckedEntry<K,V,T> checkedEntry(Map.Entry<K,V> e,
2805 >                                                            Class<T> valueType) {
2806 >                return new CheckedEntry<K,V,T>(e, valueType);
2807              }
2808  
2809              /**
# Line 2763 | Line 2811 | public class Collections {
2811               * the client from modifying the backing Map, by short-circuiting
2812               * the setValue method, and it protects the backing Map against
2813               * an ill-behaved Map.Entry that attempts to modify another
2814 <             * Map Entry when asked to perform an equality check.
2814 >             * Map.Entry when asked to perform an equality check.
2815               */
2816 <            private static class CheckedEntry<K,V> implements Map.Entry<K,V> {
2817 <                private Map.Entry<K, V> e;
2818 <                private Class<V> valueType;
2816 >            private static class CheckedEntry<K,V,T> implements Map.Entry<K,V> {
2817 >                private final Map.Entry<K, V> e;
2818 >                private final Class<T> valueType;
2819  
2820 <                CheckedEntry(Map.Entry<K, V> e, Class<V> valueType) {
2820 >                CheckedEntry(Map.Entry<K, V> e, Class<T> valueType) {
2821                      this.e = e;
2822                      this.valueType = valueType;
2823                  }
# Line 2779 | Line 2827 | public class Collections {
2827                  public int hashCode()    { return e.hashCode(); }
2828                  public String toString() { return e.toString(); }
2829  
2782
2830                  public V setValue(V value) {
2831 <                    if (!valueType.isInstance(value))
2832 <                        throw new ClassCastException("Attempt to insert " +
2786 <                        value.getClass() +
2787 <                        " value into collection with value type " + valueType);
2831 >                    if (value != null && !valueType.isInstance(value))
2832 >                        throw new ClassCastException(badValueMsg(value));
2833                      return e.setValue(value);
2834                  }
2835  
2836 +                private String badValueMsg(Object value) {
2837 +                    return "Attempt to insert " + value.getClass() +
2838 +                        " value into map with value type " + valueType;
2839 +                }
2840 +
2841                  public boolean equals(Object o) {
2842 +                    if (o == this)
2843 +                        return true;
2844                      if (!(o instanceof Map.Entry))
2845                          return false;
2846 <                    Map.Entry t = (Map.Entry)o;
2847 <                    return eq(e.getKey(),   t.getKey()) &&
2796 <                           eq(e.getValue(), t.getValue());
2846 >                    return e.equals(new AbstractMap.SimpleImmutableEntry
2847 >                                    <Object, Object>((Map.Entry<?,?>)o));
2848                  }
2849              }
2850          }
2851      }
2852  
2853      /**
2854 <     * Returns a dynamically typesafe view of the specified sorted map.  Any
2855 <     * attempt to insert a mapping whose key or value have the wrong type will
2856 <     * result in an immediate <tt>ClassCastException</tt>.  Similarly, any
2857 <     * attempt to modify the value currently associated with a key will result
2858 <     * in an immediate <tt>ClassCastException</tt>, whether the modification
2859 <     * is attempted directly through the map itself, or through a {@link
2860 <     * Map.Entry} instance obtained from the map's {@link Map#entrySet() entry
2861 <     * set} view.
2854 >     * Returns a dynamically typesafe view of the specified sorted map.
2855 >     * Any attempt to insert a mapping whose key or value have the wrong
2856 >     * type will result in an immediate {@link ClassCastException}.
2857 >     * Similarly, any attempt to modify the value currently associated with
2858 >     * a key will result in an immediate {@link ClassCastException},
2859 >     * whether the modification is attempted directly through the map
2860 >     * itself, or through a {@link Map.Entry} instance obtained from the
2861 >     * map's {@link Map#entrySet() entry set} view.
2862       *
2863       * <p>Assuming a map contains no incorrectly typed keys or values
2864       * prior to the time a dynamically typesafe view is generated, and
# Line 2816 | Line 2867 | public class Collections {
2867       * map cannot contain an incorrectly typed key or value.
2868       *
2869       * <p>A discussion of the use of dynamically typesafe views may be
2870 <     * found in the documentation for the {@link #checkedCollection checkedCollection}
2871 <     * method.
2870 >     * found in the documentation for the {@link #checkedCollection
2871 >     * checkedCollection} method.
2872       *
2873       * <p>The returned map will be serializable if the specified map is
2874       * serializable.
2875       *
2876 +     * <p>Since {@code null} is considered to be a value of any reference
2877 +     * type, the returned map permits insertion of null keys or values
2878 +     * whenever the backing map does.
2879 +     *
2880       * @param m the map for which a dynamically typesafe view is to be
2881 <     *             returned
2882 <     * @param keyType the type of key that <tt>m</tt> is permitted to hold
2883 <     * @param valueType the type of value that <tt>m</tt> is permitted to hold
2881 >     *          returned
2882 >     * @param keyType the type of key that {@code m} is permitted to hold
2883 >     * @param valueType the type of value that {@code m} is permitted to hold
2884       * @return a dynamically typesafe view of the specified map
2885       * @since 1.5
2886       */
# Line 2856 | Line 2911 | public class Collections {
2911          public K lastKey()                        { return sm.lastKey(); }
2912  
2913          public SortedMap<K,V> subMap(K fromKey, K toKey) {
2914 <            return new CheckedSortedMap<K,V>(sm.subMap(fromKey, toKey),
2915 <                                             keyType, valueType);
2914 >            return checkedSortedMap(sm.subMap(fromKey, toKey),
2915 >                                    keyType, valueType);
2916          }
2862
2917          public SortedMap<K,V> headMap(K toKey) {
2918 <            return new CheckedSortedMap<K,V>(sm.headMap(toKey),
2865 <                                             keyType, valueType);
2918 >            return checkedSortedMap(sm.headMap(toKey), keyType, valueType);
2919          }
2867
2920          public SortedMap<K,V> tailMap(K fromKey) {
2921 <            return new CheckedSortedMap<K,V>(sm.tailMap(fromKey),
2870 <                                             keyType, valueType);
2921 >            return checkedSortedMap(sm.tailMap(fromKey), keyType, valueType);
2922          }
2923      }
2924  
2925 <    // Miscellaneous
2925 >    // Empty collections
2926 >
2927 >    /**
2928 >     * Returns an iterator that has no elements.  More precisely,
2929 >     *
2930 >     * <ul compact>
2931 >     *
2932 >     * <li>{@link Iterator#hasNext hasNext} always returns {@code
2933 >     * false}.
2934 >     *
2935 >     * <li>{@link Iterator#next next} always throws {@link
2936 >     * NoSuchElementException}.
2937 >     *
2938 >     * <li>{@link Iterator#remove remove} always throws {@link
2939 >     * IllegalStateException}.
2940 >     *
2941 >     * </ul>
2942 >     *
2943 >     * <p>Implementations of this method are permitted, but not
2944 >     * required, to return the same object from multiple invocations.
2945 >     *
2946 >     * @return an empty iterator
2947 >     * @since 1.7
2948 >     */
2949 >    @SuppressWarnings("unchecked")
2950 >    public static <T> Iterator<T> emptyIterator() {
2951 >        return (Iterator<T>) EmptyIterator.EMPTY_ITERATOR;
2952 >    }
2953 >
2954 >    private static class EmptyIterator<E> implements Iterator<E> {
2955 >        static final EmptyIterator<Object> EMPTY_ITERATOR
2956 >            = new EmptyIterator<Object>();
2957 >
2958 >        public boolean hasNext() { return false; }
2959 >        public E next() { throw new NoSuchElementException(); }
2960 >        public void remove() { throw new IllegalStateException(); }
2961 >    }
2962 >
2963 >    /**
2964 >     * Returns a list iterator that has no elements.  More precisely,
2965 >     *
2966 >     * <ul compact>
2967 >     *
2968 >     * <li>{@link Iterator#hasNext hasNext} and {@link
2969 >     * ListIterator#hasPrevious hasPrevious} always return {@code
2970 >     * false}.
2971 >     *
2972 >     * <li>{@link Iterator#next next} and {@link ListIterator#previous
2973 >     * previous} always throw {@link NoSuchElementException}.
2974 >     *
2975 >     * <li>{@link Iterator#remove remove} and {@link ListIterator#set
2976 >     * set} always throw {@link IllegalStateException}.
2977 >     *
2978 >     * <li>{@link ListIterator#add add} always throws {@link
2979 >     * UnsupportedOperationException}.
2980 >     *
2981 >     * <li>{@link ListIterator#nextIndex nextIndex} always returns
2982 >     * {@code 0} .
2983 >     *
2984 >     * <li>{@link ListIterator#previousIndex previousIndex} always
2985 >     * returns {@code -1}.
2986 >     *
2987 >     * </ul>
2988 >     *
2989 >     * <p>Implementations of this method are permitted, but not
2990 >     * required, to return the same object from multiple invocations.
2991 >     *
2992 >     * @return an empty list iterator
2993 >     * @since 1.7
2994 >     */
2995 >    @SuppressWarnings("unchecked")
2996 >    public static <T> ListIterator<T> emptyListIterator() {
2997 >        return (ListIterator<T>) EmptyListIterator.EMPTY_ITERATOR;
2998 >    }
2999 >
3000 >    private static class EmptyListIterator<E>
3001 >        extends EmptyIterator<E>
3002 >        implements ListIterator<E>
3003 >    {
3004 >        static final EmptyListIterator<Object> EMPTY_ITERATOR
3005 >            = new EmptyListIterator<Object>();
3006 >
3007 >        public boolean hasPrevious() { return false; }
3008 >        public E previous() { throw new NoSuchElementException(); }
3009 >        public int nextIndex()     { return 0; }
3010 >        public int previousIndex() { return -1; }
3011 >        public void set(E e) { throw new IllegalStateException(); }
3012 >        public void add(E e) { throw new UnsupportedOperationException(); }
3013 >    }
3014 >
3015 >    /**
3016 >     * Returns an enumeration that has no elements.  More precisely,
3017 >     *
3018 >     * <ul compact>
3019 >     *
3020 >     * <li>{@link Enumeration#hasMoreElements hasMoreElements} always
3021 >     * returns {@code false}.
3022 >     *
3023 >     * <li> {@link Enumeration#nextElement nextElement} always throws
3024 >     * {@link NoSuchElementException}.
3025 >     *
3026 >     * </ul>
3027 >     *
3028 >     * <p>Implementations of this method are permitted, but not
3029 >     * required, to return the same object from multiple invocations.
3030 >     *
3031 >     * @return an empty enumeration
3032 >     * @since 1.7
3033 >     */
3034 >    @SuppressWarnings("unchecked")
3035 >    public static <T> Enumeration<T> emptyEnumeration() {
3036 >        return (Enumeration<T>) EmptyEnumeration.EMPTY_ENUMERATION;
3037 >    }
3038 >
3039 >    private static class EmptyEnumeration<E> implements Enumeration<E> {
3040 >        static final EmptyEnumeration<Object> EMPTY_ENUMERATION
3041 >            = new EmptyEnumeration<Object>();
3042 >
3043 >        public boolean hasMoreElements() { return false; }
3044 >        public E nextElement() { throw new NoSuchElementException(); }
3045 >    }
3046  
3047      /**
3048       * The empty set (immutable).  This set is serializable.
3049       *
3050       * @see #emptySet()
3051       */
3052 <    public static final Set EMPTY_SET = new EmptySet();
3052 >    @SuppressWarnings("unchecked")
3053 >    public static final Set EMPTY_SET = new EmptySet<Object>();
3054  
3055      /**
3056       * Returns the empty set (immutable).  This set is serializable.
# Line 2896 | Line 3068 | public class Collections {
3068       * @see #EMPTY_SET
3069       * @since 1.5
3070       */
3071 +    @SuppressWarnings("unchecked")
3072      public static final <T> Set<T> emptySet() {
3073 <        return (Set<T>) EMPTY_SET;
3073 >        return (Set<T>) EMPTY_SET;
3074      }
3075  
3076      /**
3077       * @serial include
3078       */
3079 <    private static class EmptySet extends AbstractSet<Object> implements Serializable {
3080 <        // use serialVersionUID from JDK 1.2.2 for interoperability
3081 <        private static final long serialVersionUID = 1582296315990362920L;
3079 >    private static class EmptySet<E>
3080 >        extends AbstractSet<E>
3081 >        implements Serializable
3082 >    {
3083 >        private static final long serialVersionUID = 1582296315990362920L;
3084  
3085 <        public Iterator<Object> iterator() {
2911 <            return new Iterator<Object>() {
2912 <                public boolean hasNext() {
2913 <                    return false;
2914 <                }
2915 <                public Object next() {
2916 <                    throw new NoSuchElementException();
2917 <                }
2918 <                public void remove() {
2919 <                    throw new UnsupportedOperationException();
2920 <                }
2921 <            };
2922 <        }
3085 >        public Iterator<E> iterator() { return emptyIterator(); }
3086  
3087          public int size() {return 0;}
3088 +        public boolean isEmpty() {return true;}
3089  
3090          public boolean contains(Object obj) {return false;}
3091 +        public boolean containsAll(Collection<?> c) { return c.isEmpty(); }
3092 +
3093 +        public Object[] toArray() { return new Object[0]; }
3094 +
3095 +        public <T> T[] toArray(T[] a) {
3096 +            if (a.length > 0)
3097 +                a[0] = null;
3098 +            return a;
3099 +        }
3100  
3101          // Preserves singleton property
3102          private Object readResolve() {
# Line 2936 | Line 3109 | public class Collections {
3109       *
3110       * @see #emptyList()
3111       */
3112 <    public static final List EMPTY_LIST = new EmptyList();
3112 >    @SuppressWarnings("unchecked")
3113 >    public static final List EMPTY_LIST = new EmptyList<Object>();
3114  
3115      /**
3116       * Returns the empty list (immutable).  This list is serializable.
# Line 2953 | Line 3127 | public class Collections {
3127       * @see #EMPTY_LIST
3128       * @since 1.5
3129       */
3130 +    @SuppressWarnings("unchecked")
3131      public static final <T> List<T> emptyList() {
3132 <        return (List<T>) EMPTY_LIST;
3132 >        return (List<T>) EMPTY_LIST;
3133      }
3134  
3135      /**
3136       * @serial include
3137       */
3138 <    private static class EmptyList
3139 <        extends AbstractList<Object>
3140 <        implements RandomAccess, Serializable {
3141 <        // use serialVersionUID from JDK 1.2.2 for interoperability
3142 <        private static final long serialVersionUID = 8842843931221139166L;
3138 >    private static class EmptyList<E>
3139 >        extends AbstractList<E>
3140 >        implements RandomAccess, Serializable {
3141 >        private static final long serialVersionUID = 8842843931221139166L;
3142 >
3143 >        public Iterator<E> iterator() {
3144 >            return emptyIterator();
3145 >        }
3146 >        public ListIterator<E> listIterator() {
3147 >            return emptyListIterator();
3148 >        }
3149  
3150          public int size() {return 0;}
3151 +        public boolean isEmpty() {return true;}
3152  
3153          public boolean contains(Object obj) {return false;}
3154 +        public boolean containsAll(Collection<?> c) { return c.isEmpty(); }
3155 +
3156 +        public Object[] toArray() { return new Object[0]; }
3157 +
3158 +        public <T> T[] toArray(T[] a) {
3159 +            if (a.length > 0)
3160 +                a[0] = null;
3161 +            return a;
3162 +        }
3163  
3164 <        public Object get(int index) {
3164 >        public E get(int index) {
3165              throw new IndexOutOfBoundsException("Index: "+index);
3166          }
3167  
3168 +        public boolean equals(Object o) {
3169 +            return (o instanceof List) && ((List<?>)o).isEmpty();
3170 +        }
3171 +
3172 +        public int hashCode() { return 1; }
3173 +
3174          // Preserves singleton property
3175          private Object readResolve() {
3176              return EMPTY_LIST;
# Line 2986 | Line 3183 | public class Collections {
3183       * @see #emptyMap()
3184       * @since 1.3
3185       */
3186 <    public static final Map EMPTY_MAP = new EmptyMap();
3186 >    @SuppressWarnings("unchecked")
3187 >    public static final Map EMPTY_MAP = new EmptyMap<Object,Object>();
3188  
3189      /**
3190       * Returns the empty map (immutable).  This map is serializable.
# Line 3003 | Line 3201 | public class Collections {
3201       * @see #EMPTY_MAP
3202       * @since 1.5
3203       */
3204 +    @SuppressWarnings("unchecked")
3205      public static final <K,V> Map<K,V> emptyMap() {
3206 <        return (Map<K,V>) EMPTY_MAP;
3206 >        return (Map<K,V>) EMPTY_MAP;
3207      }
3208  
3209 <    private static class EmptyMap
3210 <        extends AbstractMap<Object,Object>
3211 <        implements Serializable {
3212 <
3209 >    /**
3210 >     * @serial include
3211 >     */
3212 >    private static class EmptyMap<K,V>
3213 >        extends AbstractMap<K,V>
3214 >        implements Serializable
3215 >    {
3216          private static final long serialVersionUID = 6428348081105594320L;
3217  
3218          public int size()                          {return 0;}
3017
3219          public boolean isEmpty()                   {return true;}
3019
3220          public boolean containsKey(Object key)     {return false;}
3021
3221          public boolean containsValue(Object value) {return false;}
3222 <
3223 <        public Object get(Object key)              {return null;}
3224 <
3225 <        public Set<Object> keySet()                {return Collections.<Object>emptySet();}
3027 <
3028 <        public Collection<Object> values()         {return Collections.<Object>emptySet();}
3029 <
3030 <        public Set<Map.Entry<Object,Object>> entrySet() {
3031 <            return Collections.emptySet();
3032 <        }
3222 >        public V get(Object key)                   {return null;}
3223 >        public Set<K> keySet()                     {return emptySet();}
3224 >        public Collection<V> values()              {return emptySet();}
3225 >        public Set<Map.Entry<K,V>> entrySet()      {return emptySet();}
3226  
3227          public boolean equals(Object o) {
3228 <            return (o instanceof Map) && ((Map)o).size()==0;
3228 >            return (o instanceof Map) && ((Map<?,?>)o).isEmpty();
3229          }
3230  
3231          public int hashCode()                      {return 0;}
# Line 3043 | Line 3236 | public class Collections {
3236          }
3237      }
3238  
3239 +    // Singleton collections
3240 +
3241      /**
3242       * Returns an immutable set containing only the specified object.
3243       * The returned set is serializable.
# Line 3051 | Line 3246 | public class Collections {
3246       * @return an immutable set containing only the specified object.
3247       */
3248      public static <T> Set<T> singleton(T o) {
3249 <        return new SingletonSet<T>(o);
3249 >        return new SingletonSet<T>(o);
3250 >    }
3251 >
3252 >    static <E> Iterator<E> singletonIterator(final E e) {
3253 >        return new Iterator<E>() {
3254 >            private boolean hasNext = true;
3255 >            public boolean hasNext() {
3256 >                return hasNext;
3257 >            }
3258 >            public E next() {
3259 >                if (hasNext) {
3260 >                    hasNext = false;
3261 >                    return e;
3262 >                }
3263 >                throw new NoSuchElementException();
3264 >            }
3265 >            public void remove() {
3266 >                throw new UnsupportedOperationException();
3267 >            }
3268 >        };
3269      }
3270  
3271      /**
3272       * @serial include
3273       */
3274      private static class SingletonSet<E>
3275 <        extends AbstractSet<E>
3276 <        implements Serializable
3275 >        extends AbstractSet<E>
3276 >        implements Serializable
3277      {
3278 <        // use serialVersionUID from JDK 1.2.2 for interoperability
3065 <        private static final long serialVersionUID = 3193687207550431679L;
3278 >        private static final long serialVersionUID = 3193687207550431679L;
3279  
3280          final private E element;
3281  
3282          SingletonSet(E e) {element = e;}
3283  
3284          public Iterator<E> iterator() {
3285 <            return new Iterator<E>() {
3073 <                private boolean hasNext = true;
3074 <                public boolean hasNext() {
3075 <                    return hasNext;
3076 <                }
3077 <                public E next() {
3078 <                    if (hasNext) {
3079 <                        hasNext = false;
3080 <                        return element;
3081 <                    }
3082 <                    throw new NoSuchElementException();
3083 <                }
3084 <                public void remove() {
3085 <                    throw new UnsupportedOperationException();
3086 <                }
3087 <            };
3285 >            return singletonIterator(element);
3286          }
3287  
3288          public int size() {return 1;}
# Line 3101 | Line 3299 | public class Collections {
3299       * @since 1.3
3300       */
3301      public static <T> List<T> singletonList(T o) {
3302 <        return new SingletonList<T>(o);
3302 >        return new SingletonList<T>(o);
3303      }
3304  
3305 +    /**
3306 +     * @serial include
3307 +     */
3308      private static class SingletonList<E>
3309 <        extends AbstractList<E>
3310 <        implements RandomAccess, Serializable {
3309 >        extends AbstractList<E>
3310 >        implements RandomAccess, Serializable {
3311  
3312 <        static final long serialVersionUID = 3093736618740652951L;
3312 >        private static final long serialVersionUID = 3093736618740652951L;
3313  
3314          private final E element;
3315  
3316          SingletonList(E obj)                {element = obj;}
3317  
3318 +        public Iterator<E> iterator() {
3319 +            return singletonIterator(element);
3320 +        }
3321 +
3322          public int size()                   {return 1;}
3323  
3324          public boolean contains(Object obj) {return eq(obj, element);}
# Line 3136 | Line 3341 | public class Collections {
3341       * @since 1.3
3342       */
3343      public static <K,V> Map<K,V> singletonMap(K key, V value) {
3344 <        return new SingletonMap<K,V>(key, value);
3344 >        return new SingletonMap<K,V>(key, value);
3345      }
3346  
3347 +    /**
3348 +     * @serial include
3349 +     */
3350      private static class SingletonMap<K,V>
3351 <          extends AbstractMap<K,V>
3352 <          implements Serializable {
3353 <        private static final long serialVersionUID = -6979724477215052911L;
3351 >          extends AbstractMap<K,V>
3352 >          implements Serializable {
3353 >        private static final long serialVersionUID = -6979724477215052911L;
3354  
3355          private final K k;
3356 <        private final V v;
3356 >        private final V v;
3357  
3358          SingletonMap(K key, V value) {
3359              k = key;
# Line 3166 | Line 3374 | public class Collections {
3374          private transient Set<Map.Entry<K,V>> entrySet = null;
3375          private transient Collection<V> values = null;
3376  
3377 <        public Set<K> keySet() {
3378 <            if (keySet==null)
3379 <                keySet = singleton(k);
3380 <            return keySet;
3381 <        }
3382 <
3383 <        public Set<Map.Entry<K,V>> entrySet() {
3384 <            if (entrySet==null)
3385 <                entrySet = Collections.<Map.Entry<K,V>>singleton(
3386 <                    new SimpleImmutableEntry<K,V>(k, v));
3387 <            return entrySet;
3388 <        }
3389 <
3390 <        public Collection<V> values() {
3391 <            if (values==null)
3392 <                values = singleton(v);
3393 <            return values;
3394 <        }
3377 >        public Set<K> keySet() {
3378 >            if (keySet==null)
3379 >                keySet = singleton(k);
3380 >            return keySet;
3381 >        }
3382 >
3383 >        public Set<Map.Entry<K,V>> entrySet() {
3384 >            if (entrySet==null)
3385 >                entrySet = Collections.<Map.Entry<K,V>>singleton(
3386 >                    new SimpleImmutableEntry<K,V>(k, v));
3387 >            return entrySet;
3388 >        }
3389 >
3390 >        public Collection<V> values() {
3391 >            if (values==null)
3392 >                values = singleton(v);
3393 >            return values;
3394 >        }
3395  
3396      }
3397  
3398 +    // Miscellaneous
3399 +
3400      /**
3401       * Returns an immutable list consisting of <tt>n</tt> copies of the
3402       * specified object.  The newly allocated data object is tiny (it contains
# Line 3197 | Line 3407 | public class Collections {
3407       * @param  n the number of elements in the returned list.
3408       * @param  o the element to appear repeatedly in the returned list.
3409       * @return an immutable list consisting of <tt>n</tt> copies of the
3410 <     *         specified object.
3410 >     *         specified object.
3411       * @throws IllegalArgumentException if n &lt; 0.
3412       * @see    List#addAll(Collection)
3413       * @see    List#addAll(int, Collection)
3414       */
3415      public static <T> List<T> nCopies(int n, T o) {
3416 <        if (n < 0)
3417 <            throw new IllegalArgumentException("List length = " + n);
3416 >        if (n < 0)
3417 >            throw new IllegalArgumentException("List length = " + n);
3418          return new CopiesList<T>(n, o);
3419      }
3420  
# Line 3212 | Line 3422 | public class Collections {
3422       * @serial include
3423       */
3424      private static class CopiesList<E>
3425 <        extends AbstractList<E>
3426 <        implements RandomAccess, Serializable
3425 >        extends AbstractList<E>
3426 >        implements RandomAccess, Serializable
3427      {
3428 <        static final long serialVersionUID = 2739099268398711800L;
3428 >        private static final long serialVersionUID = 2739099268398711800L;
3429  
3430          final int n;
3431          final E element;
3432  
3433          CopiesList(int n, E e) {
3434 <            assert n >= 0;
3434 >            assert n >= 0;
3435              this.n = n;
3436              element = e;
3437          }
# Line 3234 | Line 3444 | public class Collections {
3444              return n != 0 && eq(obj, element);
3445          }
3446  
3447 <        public int indexOf(Object o) {
3448 <            return contains(o) ? 0 : -1;
3449 <        }
3450 <
3451 <        public int lastIndexOf(Object o) {
3452 <            return contains(o) ? n - 1 : -1;
3453 <        }
3447 >        public int indexOf(Object o) {
3448 >            return contains(o) ? 0 : -1;
3449 >        }
3450 >
3451 >        public int lastIndexOf(Object o) {
3452 >            return contains(o) ? n - 1 : -1;
3453 >        }
3454  
3455          public E get(int index) {
3456              if (index < 0 || index >= n)
# Line 3249 | Line 3459 | public class Collections {
3459              return element;
3460          }
3461  
3462 <        public Object[] toArray() {
3463 <            final Object[] a = new Object[n];
3464 <            if (element != null)
3465 <                Arrays.fill(a, 0, n, element);
3466 <            return a;
3467 <        }
3468 <
3469 <        public <T> T[] toArray(T[] a) {
3470 <            final int n = this.n;
3471 <            if (a.length < n) {
3472 <                a = (T[])java.lang.reflect.Array
3473 <                    .newInstance(a.getClass().getComponentType(), n);
3474 <                if (element != null)
3475 <                    Arrays.fill(a, 0, n, element);
3476 <            } else {
3477 <                Arrays.fill(a, 0, n, element);
3478 <                if (a.length > n)
3479 <                    a[n] = null;
3480 <            }
3481 <            return a;
3482 <        }
3483 <
3484 <        public List<E> subList(int fromIndex, int toIndex) {
3485 <            if (fromIndex < 0)
3486 <                throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
3487 <            if (toIndex > n)
3488 <                throw new IndexOutOfBoundsException("toIndex = " + toIndex);
3489 <            if (fromIndex > toIndex)
3490 <                throw new IllegalArgumentException("fromIndex(" + fromIndex +
3491 <                                                   ") > toIndex(" + toIndex + ")");
3492 <            return new CopiesList(toIndex - fromIndex, element);
3493 <        }
3462 >        public Object[] toArray() {
3463 >            final Object[] a = new Object[n];
3464 >            if (element != null)
3465 >                Arrays.fill(a, 0, n, element);
3466 >            return a;
3467 >        }
3468 >
3469 >        public <T> T[] toArray(T[] a) {
3470 >            final int n = this.n;
3471 >            if (a.length < n) {
3472 >                a = (T[])java.lang.reflect.Array
3473 >                    .newInstance(a.getClass().getComponentType(), n);
3474 >                if (element != null)
3475 >                    Arrays.fill(a, 0, n, element);
3476 >            } else {
3477 >                Arrays.fill(a, 0, n, element);
3478 >                if (a.length > n)
3479 >                    a[n] = null;
3480 >            }
3481 >            return a;
3482 >        }
3483 >
3484 >        public List<E> subList(int fromIndex, int toIndex) {
3485 >            if (fromIndex < 0)
3486 >                throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
3487 >            if (toIndex > n)
3488 >                throw new IndexOutOfBoundsException("toIndex = " + toIndex);
3489 >            if (fromIndex > toIndex)
3490 >                throw new IllegalArgumentException("fromIndex(" + fromIndex +
3491 >                                                   ") > toIndex(" + toIndex + ")");
3492 >            return new CopiesList<E>(toIndex - fromIndex, element);
3493 >        }
3494      }
3495  
3496      /**
# Line 3292 | Line 3502 | public class Collections {
3502       * objects that implement the <tt>Comparable</tt> interface in
3503       * reverse-natural-order.  For example, suppose a is an array of
3504       * strings. Then: <pre>
3505 <     *          Arrays.sort(a, Collections.reverseOrder());
3505 >     *          Arrays.sort(a, Collections.reverseOrder());
3506       * </pre> sorts the array in reverse-lexicographic (alphabetical) order.<p>
3507       *
3508       * The returned comparator is serializable.
3509       *
3510       * @return a comparator that imposes the reverse of the <i>natural
3511 <     *         ordering</i> on a collection of objects that implement
3512 <     *         the <tt>Comparable</tt> interface.
3511 >     *         ordering</i> on a collection of objects that implement
3512 >     *         the <tt>Comparable</tt> interface.
3513       * @see Comparable
3514       */
3515      public static <T> Comparator<T> reverseOrder() {
3516 <        return (Comparator<T>) REVERSE_ORDER;
3516 >        return (Comparator<T>) ReverseComparator.REVERSE_ORDER;
3517      }
3518  
3309    private static final Comparator REVERSE_ORDER = new ReverseComparator();
3310
3519      /**
3520       * @serial include
3521       */
3522 <    private static class ReverseComparator<T>
3523 <        implements Comparator<Comparable<Object>>, Serializable {
3522 >    private static class ReverseComparator
3523 >        implements Comparator<Comparable<Object>>, Serializable {
3524 >
3525 >        private static final long serialVersionUID = 7207038068494060240L;
3526  
3527 <        // use serialVersionUID from JDK 1.2.2 for interoperability
3528 <        private static final long serialVersionUID = 7207038068494060240L;
3527 >        static final ReverseComparator REVERSE_ORDER
3528 >            = new ReverseComparator();
3529  
3530          public int compare(Comparable<Object> c1, Comparable<Object> c2) {
3531              return c2.compareTo(c1);
3532          }
3533 +
3534 +        private Object readResolve() { return reverseOrder(); }
3535      }
3536  
3537      /**
# Line 3333 | Line 3545 | public class Collections {
3545       * comparator is also serializable or null).
3546       *
3547       * @return a comparator that imposes the reverse ordering of the
3548 <     *     specified comparator.
3548 >     *         specified comparator
3549       * @since 1.5
3550       */
3551      public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) {
3552          if (cmp == null)
3553 <            return new ReverseComparator();  // Unchecked warning!!
3553 >            return reverseOrder();
3554 >
3555 >        if (cmp instanceof ReverseComparator2)
3556 >            return ((ReverseComparator2<T>)cmp).cmp;
3557  
3558          return new ReverseComparator2<T>(cmp);
3559      }
# Line 3358 | Line 3573 | public class Collections {
3573           *
3574           * @serial
3575           */
3576 <        private Comparator<T> cmp;
3576 >        final Comparator<T> cmp;
3577  
3578          ReverseComparator2(Comparator<T> cmp) {
3579              assert cmp != null;
# Line 3368 | Line 3583 | public class Collections {
3583          public int compare(T t1, T t2) {
3584              return cmp.compare(t2, t1);
3585          }
3586 +
3587 +        public boolean equals(Object o) {
3588 +            return (o == this) ||
3589 +                (o instanceof ReverseComparator2 &&
3590 +                 cmp.equals(((ReverseComparator2)o).cmp));
3591 +        }
3592 +
3593 +        public int hashCode() {
3594 +            return cmp.hashCode() ^ Integer.MIN_VALUE;
3595 +        }
3596      }
3597  
3598      /**
# Line 3380 | Line 3605 | public class Collections {
3605       * @see Enumeration
3606       */
3607      public static <T> Enumeration<T> enumeration(final Collection<T> c) {
3608 <        return new Enumeration<T>() {
3609 <            Iterator<T> i = c.iterator();
3608 >        return new Enumeration<T>() {
3609 >            private final Iterator<T> i = c.iterator();
3610  
3611 <            public boolean hasMoreElements() {
3612 <                return i.hasNext();
3613 <            }
3614 <
3615 <            public T nextElement() {
3616 <                return i.next();
3617 <            }
3611 >            public boolean hasMoreElements() {
3612 >                return i.hasNext();
3613 >            }
3614 >
3615 >            public T nextElement() {
3616 >                return i.next();
3617 >            }
3618          };
3619      }
3620  
# Line 3418 | Line 3643 | public class Collections {
3643      /**
3644       * Returns true if the specified arguments are equal, or both null.
3645       */
3646 <    private static boolean eq(Object o1, Object o2) {
3647 <        return (o1==null ? o2==null : o1.equals(o2));
3646 >    static boolean eq(Object o1, Object o2) {
3647 >        return o1==null ? o2==null : o1.equals(o2);
3648      }
3649  
3650      /**
# Line 3557 | Line 3782 | public class Collections {
3782          return new SetFromMap<E>(map);
3783      }
3784  
3785 +    /**
3786 +     * @serial include
3787 +     */
3788      private static class SetFromMap<E> extends AbstractSet<E>
3789          implements Set<E>, Serializable
3790      {
3791          private final Map<E, Boolean> m;  // The backing map
3792 <        private transient Set<E> keySet;  // Its keySet
3792 >        private transient Set<E> s;       // Its keySet
3793  
3794          SetFromMap(Map<E, Boolean> map) {
3795              if (!map.isEmpty())
3796                  throw new IllegalArgumentException("Map is non-empty");
3797              m = map;
3798 <            keySet = map.keySet();
3798 >            s = map.keySet();
3799          }
3800  
3801 +        public void clear()               {        m.clear(); }
3802          public int size()                 { return m.size(); }
3803          public boolean isEmpty()          { return m.isEmpty(); }
3804          public boolean contains(Object o) { return m.containsKey(o); }
3576        public Iterator<E> iterator()     { return keySet.iterator(); }
3577        public Object[] toArray()         { return keySet.toArray(); }
3578        public <T> T[] toArray(T[] a)     { return keySet.toArray(a); }
3579        public boolean add(E e) {
3580            return m.put(e, Boolean.TRUE) == null;
3581        }
3805          public boolean remove(Object o)   { return m.remove(o) != null; }
3806 <
3807 <        public boolean removeAll(Collection<?> c) {
3808 <            return keySet.removeAll(c);
3809 <        }
3810 <        public boolean retainAll(Collection<?> c) {
3811 <            return keySet.retainAll(c);
3812 <        }
3813 <        public void clear()               { m.clear(); }
3814 <        public boolean equals(Object o)   { return keySet.equals(o); }
3815 <        public int hashCode()             { return keySet.hashCode(); }
3806 >        public boolean add(E e) { return m.put(e, Boolean.TRUE) == null; }
3807 >        public Iterator<E> iterator()     { return s.iterator(); }
3808 >        public Object[] toArray()         { return s.toArray(); }
3809 >        public <T> T[] toArray(T[] a)     { return s.toArray(a); }
3810 >        public String toString()          { return s.toString(); }
3811 >        public int hashCode()             { return s.hashCode(); }
3812 >        public boolean equals(Object o)   { return o == this || s.equals(o); }
3813 >        public boolean containsAll(Collection<?> c) {return s.containsAll(c);}
3814 >        public boolean removeAll(Collection<?> c)   {return s.removeAll(c);}
3815 >        public boolean retainAll(Collection<?> c)   {return s.retainAll(c);}
3816 >        // addAll is the only inherited implementation
3817  
3818          private static final long serialVersionUID = 2454657854757543876L;
3819  
3820 <        private void readObject(java.io.ObjectInputStream s)
3820 >        private void readObject(java.io.ObjectInputStream stream)
3821              throws IOException, ClassNotFoundException
3822          {
3823 <            s.defaultReadObject();
3824 <            keySet = m.keySet();
3823 >            stream.defaultReadObject();
3824 >            s = m.keySet();
3825          }
3826      }
3827  
# Line 3608 | Line 3832 | public class Collections {
3832       * view can be useful when you would like to use a method
3833       * requiring a <tt>Queue</tt> but you need Lifo ordering.
3834       *
3835 +     * <p>Each method invocation on the queue returned by this method
3836 +     * results in exactly one method invocation on the backing deque, with
3837 +     * one exception.  The {@link Queue#addAll addAll} method is
3838 +     * implemented as a sequence of {@link Deque#addFirst addFirst}
3839 +     * invocations on the backing deque.
3840 +     *
3841       * @param deque the deque
3842       * @return the queue
3843       * @since  1.6
# Line 3616 | Line 3846 | public class Collections {
3846          return new AsLIFOQueue<T>(deque);
3847      }
3848  
3849 +    /**
3850 +     * @serial include
3851 +     */
3852      static class AsLIFOQueue<E> extends AbstractQueue<E>
3853          implements Queue<E>, Serializable {
3854 <        private static final long serialVersionUID = 1802017725587941708L;
3854 >        private static final long serialVersionUID = 1802017725587941708L;
3855          private final Deque<E> q;
3856 <        AsLIFOQueue(Deque<E> q)            { this.q = q; }
3857 <        public boolean add(E e)            { q.addFirst(e); return true; }
3858 <        public boolean offer(E e)          { return q.offerFirst(e); }
3859 <        public E poll()                    { return q.pollFirst(); }
3860 <        public E remove()                  { return q.removeFirst(); }
3861 <        public E peek()                    { return q.peekFirst(); }
3862 <        public E element()                 { return q.getFirst(); }
3863 <        public int size()                  { return q.size(); }
3864 <        public boolean isEmpty()           { return q.isEmpty(); }
3865 <        public boolean contains(Object o)  { return q.contains(o); }
3866 <        public Iterator<E> iterator()      { return q.iterator(); }
3867 <        public Object[] toArray()          { return q.toArray(); }
3868 <        public <T> T[] toArray(T[] a)      { return q.toArray(a); }
3869 <        public boolean remove(Object o)    { return q.remove(o); }
3870 <        public void clear()                { q.clear(); }
3856 >        AsLIFOQueue(Deque<E> q)           { this.q = q; }
3857 >        public boolean add(E e)           { q.addFirst(e); return true; }
3858 >        public boolean offer(E e)         { return q.offerFirst(e); }
3859 >        public E poll()                   { return q.pollFirst(); }
3860 >        public E remove()                 { return q.removeFirst(); }
3861 >        public E peek()                   { return q.peekFirst(); }
3862 >        public E element()                { return q.getFirst(); }
3863 >        public void clear()               {        q.clear(); }
3864 >        public int size()                 { return q.size(); }
3865 >        public boolean isEmpty()          { return q.isEmpty(); }
3866 >        public boolean contains(Object o) { return q.contains(o); }
3867 >        public boolean remove(Object o)   { return q.remove(o); }
3868 >        public Iterator<E> iterator()     { return q.iterator(); }
3869 >        public Object[] toArray()         { return q.toArray(); }
3870 >        public <T> T[] toArray(T[] a)     { return q.toArray(a); }
3871 >        public String toString()          { return q.toString(); }
3872 >        public boolean containsAll(Collection<?> c) {return q.containsAll(c);}
3873 >        public boolean removeAll(Collection<?> c)   {return q.removeAll(c);}
3874 >        public boolean retainAll(Collection<?> c)   {return q.retainAll(c);}
3875 >        // We use inherited addAll; forwarding addAll would be wrong
3876      }
3877   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines