1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.  Oracle designates this
9  * particular file as subject to the "Classpath" exception as provided
10  * by Oracle in the LICENSE file that accompanied this code.
11  *
12  * This code is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * version 2 for more details (a copy is included in the LICENSE file that
16  * accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License version
19  * 2 along with this work; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23  * or visit www.oracle.com if you need additional information or have any
24  * questions.
25  */
26 
27 package java.util;
28 
29 import java.io.IOException;
30 import java.io.ObjectInputStream;
31 import java.io.ObjectOutputStream;
32 import java.io.Serializable;
33 import java.lang.reflect.Array;
34 import java.util.function.BiConsumer;
35 import java.util.function.BiFunction;
36 import java.util.function.Consumer;
37 import java.util.function.Function;
38 import java.util.function.IntFunction;
39 import java.util.function.Predicate;
40 import java.util.function.UnaryOperator;
41 import java.util.random.RandomGenerator;
42 import java.util.stream.IntStream;
43 import java.util.stream.Stream;
44 import java.util.stream.StreamSupport;
45 import jdk.internal.access.SharedSecrets;
46 
47 import dalvik.system.VMRuntime;
48 
49 /**
50  * This class consists exclusively of static methods that operate on or return
51  * collections.  It contains polymorphic algorithms that operate on
52  * collections, "wrappers", which return a new collection backed by a
53  * specified collection, and a few other odds and ends.
54  *
55  * <p>The methods of this class all throw a {@code NullPointerException}
56  * if the collections or class objects provided to them are null.
57  *
58  * <p>The documentation for the polymorphic algorithms contained in this class
59  * generally includes a brief description of the <i>implementation</i>.  Such
60  * descriptions should be regarded as <i>implementation notes</i>, rather than
61  * parts of the <i>specification</i>.  Implementors should feel free to
62  * substitute other algorithms, so long as the specification itself is adhered
63  * to.  (For example, the algorithm used by {@code sort} does not have to be
64  * a mergesort, but it does have to be <i>stable</i>.)
65  *
66  * <p>The "destructive" algorithms contained in this class, that is, the
67  * algorithms that modify the collection on which they operate, are specified
68  * to throw {@code UnsupportedOperationException} if the collection does not
69  * support the appropriate mutation primitive(s), such as the {@code set}
70  * method.  These algorithms may, but are not required to, throw this
71  * exception if an invocation would have no effect on the collection.  For
72  * example, invoking the {@code sort} method on an unmodifiable list that is
73  * already sorted may or may not throw {@code UnsupportedOperationException}.
74  *
75  * <p>This class is a member of the
76  * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
77  * Java Collections Framework</a>.
78  *
79  * @author  Josh Bloch
80  * @author  Neal Gafter
81  * @see     Collection
82  * @see     Set
83  * @see     List
84  * @see     Map
85  * @since   1.2
86  */
87 
88 public class Collections {
89     // Suppresses default constructor, ensuring non-instantiability.
Collections()90     private Collections() {
91     }
92 
93     // Algorithms
94 
95     /*
96      * Tuning parameters for algorithms - Many of the List algorithms have
97      * two implementations, one of which is appropriate for RandomAccess
98      * lists, the other for "sequential."  Often, the random access variant
99      * yields better performance on small sequential access lists.  The
100      * tuning parameters below determine the cutoff point for what constitutes
101      * a "small" sequential access list for each algorithm.  The values below
102      * were empirically determined to work well for LinkedList. Hopefully
103      * they should be reasonable for other sequential access List
104      * implementations.  Those doing performance work on this code would
105      * do well to validate the values of these parameters from time to time.
106      * (The first word of each tuning parameter name is the algorithm to which
107      * it applies.)
108      */
109     private static final int BINARYSEARCH_THRESHOLD   = 5000;
110     private static final int REVERSE_THRESHOLD        =   18;
111     private static final int SHUFFLE_THRESHOLD        =    5;
112     private static final int FILL_THRESHOLD           =   25;
113     private static final int ROTATE_THRESHOLD         =  100;
114     private static final int COPY_THRESHOLD           =   10;
115     private static final int REPLACEALL_THRESHOLD     =   11;
116     private static final int INDEXOFSUBLIST_THRESHOLD =   35;
117 
118     // Android-added: List.sort() vs. Collections.sort() app compat.
119     // Added a warning in the documentation.
120     // Collections.sort() calls List.sort() for apps targeting API version >= 26
121     // (Android Oreo) but the other way around for app targeting <= 25 (Nougat).
122     /**
123      * Sorts the specified list into ascending order, according to the
124      * {@linkplain Comparable natural ordering} of its elements.
125      * All elements in the list must implement the {@link Comparable}
126      * interface.  Furthermore, all elements in the list must be
127      * <i>mutually comparable</i> (that is, {@code e1.compareTo(e2)}
128      * must not throw a {@code ClassCastException} for any elements
129      * {@code e1} and {@code e2} in the list).
130      *
131      * <p>This sort is guaranteed to be <i>stable</i>:  equal elements will
132      * not be reordered as a result of the sort.
133      *
134      * <p>The specified list must be modifiable, but need not be resizable.
135      *
136      * @implNote
137      * This implementation defers to the {@link List#sort(Comparator)}
138      * method using the specified list and a {@code null} comparator.
139      * Do not call this method from {@code List.sort()} since that can lead
140      * to infinite recursion. Apps targeting APIs {@code <= 25} observe
141      * backwards compatibility behavior where this method was implemented
142      * on top of {@link List#toArray()}, {@link ListIterator#next()} and
143      * {@link ListIterator#set(Object)}.
144      *
145      * @param  <T> the class of the objects in the list
146      * @param  list the list to be sorted.
147      * @throws ClassCastException if the list contains elements that are not
148      *         <i>mutually comparable</i> (for example, strings and integers).
149      * @throws UnsupportedOperationException if the specified list's
150      *         list-iterator does not support the {@code set} operation.
151      * @throws IllegalArgumentException (optional) if the implementation
152      *         detects that the natural ordering of the list elements is
153      *         found to violate the {@link Comparable} contract
154      * @see List#sort(Comparator)
155      */
sort(List<T> list)156     public static <T extends Comparable<? super T>> void sort(List<T> list) {
157         // Android-changed: List.sort() vs. Collections.sort() app compat.
158         // Call sort(list, null) here to be consistent with that method's
159         // (changed on Android) behavior.
160         // list.sort(null);
161         sort(list, null);
162     }
163 
164     // Android-added: List.sort() vs. Collections.sort() app compat.
165     // Added a warning in the documentation.
166     // Collections.sort() calls List.sort() for apps targeting API version >= 26
167     // (Android Oreo) but the other way around for app targeting <= 25 (Nougat).
168     /**
169      * Sorts the specified list according to the order induced by the
170      * specified comparator.  All elements in the list must be <i>mutually
171      * comparable</i> using the specified comparator (that is,
172      * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException}
173      * for any elements {@code e1} and {@code e2} in the list).
174      *
175      * <p>This sort is guaranteed to be <i>stable</i>:  equal elements will
176      * not be reordered as a result of the sort.
177      *
178      * <p>The specified list must be modifiable, but need not be resizable.
179      *
180      * @implNote
181      * This implementation defers to the {@link List#sort(Comparator)}
182      * method using the specified list and comparator.
183      * Do not call this method from {@code List.sort()} since that can lead
184      * to infinite recursion. Apps targeting APIs {@code <= 25} observe
185      * backwards compatibility behavior where this method was implemented
186      * on top of {@link List#toArray()}, {@link ListIterator#next()} and
187      * {@link ListIterator#set(Object)}.
188      *
189      * @param  <T> the class of the objects in the list
190      * @param  list the list to be sorted.
191      * @param  c the comparator to determine the order of the list.  A
192      *        {@code null} value indicates that the elements' <i>natural
193      *        ordering</i> should be used.
194      * @throws ClassCastException if the list contains elements that are not
195      *         <i>mutually comparable</i> using the specified comparator.
196      * @throws UnsupportedOperationException if the specified list's
197      *         list-iterator does not support the {@code set} operation.
198      * @throws IllegalArgumentException (optional) if the comparator is
199      *         found to violate the {@link Comparator} contract
200      * @see List#sort(Comparator)
201      */
sort(List<T> list, Comparator<? super T> c)202     public static <T> void sort(List<T> list, Comparator<? super T> c) {
203         // BEGIN Android-changed: List.sort() vs. Collections.sort() app compat.
204         // list.sort(c);
205         int targetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
206         if (targetSdkVersion > 25) {
207             list.sort(c);
208         } else {
209             // Compatibility behavior for API <= 25. http://b/33482884
210             if (list.getClass() == ArrayList.class) {
211                 Arrays.sort((T[]) ((ArrayList) list).elementData, 0, list.size(), c);
212                 return;
213             }
214 
215             Object[] a = list.toArray();
216             Arrays.sort(a, (Comparator) c);
217             ListIterator<T> i = list.listIterator();
218             for (int j = 0; j < a.length; j++) {
219                 i.next();
220                 i.set((T) a[j]);
221             }
222         }
223         // END Android-changed: List.sort() vs. Collections.sort() app compat.
224     }
225 
226 
227     /**
228      * Searches the specified list for the specified object using the binary
229      * search algorithm.  The list must be sorted into ascending order
230      * according to the {@linkplain Comparable natural ordering} of its
231      * elements (as by the {@link #sort(List)} method) prior to making this
232      * call.  If it is not sorted, the results are undefined.  If the list
233      * contains multiple elements equal to the specified object, there is no
234      * guarantee which one will be found.
235      *
236      * <p>This method runs in log(n) time for a "random access" list (which
237      * provides near-constant-time positional access).  If the specified list
238      * does not implement the {@link RandomAccess} interface and is large,
239      * this method will do an iterator-based binary search that performs
240      * O(n) link traversals and O(log n) element comparisons.
241      *
242      * @param  <T> the class of the objects in the list
243      * @param  list the list to be searched.
244      * @param  key the key to be searched for.
245      * @return the index of the search key, if it is contained in the list;
246      *         otherwise, <code>(-(<i>insertion point</i>) - 1)</code>.  The
247      *         <i>insertion point</i> is defined as the point at which the
248      *         key would be inserted into the list: the index of the first
249      *         element greater than the key, or {@code list.size()} if all
250      *         elements in the list are less than the specified key.  Note
251      *         that this guarantees that the return value will be &gt;= 0 if
252      *         and only if the key is found.
253      * @throws ClassCastException if the list contains elements that are not
254      *         <i>mutually comparable</i> (for example, strings and
255      *         integers), or the search key is not mutually comparable
256      *         with the elements of the list.
257      */
258     public static <T>
binarySearch(List<? extends Comparable<? super T>> list, T key)259     int binarySearch(List<? extends Comparable<? super T>> list, T key) {
260         if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
261             return Collections.indexedBinarySearch(list, key);
262         else
263             return Collections.iteratorBinarySearch(list, key);
264     }
265 
266     private static <T>
indexedBinarySearch(List<? extends Comparable<? super T>> list, T key)267     int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) {
268         int low = 0;
269         int high = list.size()-1;
270 
271         while (low <= high) {
272             int mid = (low + high) >>> 1;
273             Comparable<? super T> midVal = list.get(mid);
274             int cmp = midVal.compareTo(key);
275 
276             if (cmp < 0)
277                 low = mid + 1;
278             else if (cmp > 0)
279                 high = mid - 1;
280             else
281                 return mid; // key found
282         }
283         return -(low + 1);  // key not found
284     }
285 
286     private static <T>
iteratorBinarySearch(List<? extends Comparable<? super T>> list, T key)287     int iteratorBinarySearch(List<? extends Comparable<? super T>> list, T key)
288     {
289         int low = 0;
290         int high = list.size()-1;
291         ListIterator<? extends Comparable<? super T>> i = list.listIterator();
292 
293         while (low <= high) {
294             int mid = (low + high) >>> 1;
295             Comparable<? super T> midVal = get(i, mid);
296             int cmp = midVal.compareTo(key);
297 
298             if (cmp < 0)
299                 low = mid + 1;
300             else if (cmp > 0)
301                 high = mid - 1;
302             else
303                 return mid; // key found
304         }
305         return -(low + 1);  // key not found
306     }
307 
308     /**
309      * Gets the ith element from the given list by repositioning the specified
310      * list listIterator.
311      */
get(ListIterator<? extends T> i, int index)312     private static <T> T get(ListIterator<? extends T> i, int index) {
313         T obj;
314         int pos = i.nextIndex();
315         if (pos <= index) {
316             do {
317                 obj = i.next();
318             } while (pos++ < index);
319         } else {
320             do {
321                 obj = i.previous();
322             } while (--pos > index);
323         }
324         return obj;
325     }
326 
327     /**
328      * Searches the specified list for the specified object using the binary
329      * search algorithm.  The list must be sorted into ascending order
330      * according to the specified comparator (as by the
331      * {@link #sort(List, Comparator) sort(List, Comparator)}
332      * method), prior to making this call.  If it is
333      * not sorted, the results are undefined.  If the list contains multiple
334      * elements equal to the specified object, there is no guarantee which one
335      * will be found.
336      *
337      * <p>This method runs in log(n) time for a "random access" list (which
338      * provides near-constant-time positional access).  If the specified list
339      * does not implement the {@link RandomAccess} interface and is large,
340      * this method will do an iterator-based binary search that performs
341      * O(n) link traversals and O(log n) element comparisons.
342      *
343      * @param  <T> the class of the objects in the list
344      * @param  list the list to be searched.
345      * @param  key the key to be searched for.
346      * @param  c the comparator by which the list is ordered.
347      *         A {@code null} value indicates that the elements'
348      *         {@linkplain Comparable natural ordering} should be used.
349      * @return the index of the search key, if it is contained in the list;
350      *         otherwise, <code>(-(<i>insertion point</i>) - 1)</code>.  The
351      *         <i>insertion point</i> is defined as the point at which the
352      *         key would be inserted into the list: the index of the first
353      *         element greater than the key, or {@code list.size()} if all
354      *         elements in the list are less than the specified key.  Note
355      *         that this guarantees that the return value will be &gt;= 0 if
356      *         and only if the key is found.
357      * @throws ClassCastException if the list contains elements that are not
358      *         <i>mutually comparable</i> using the specified comparator,
359      *         or the search key is not mutually comparable with the
360      *         elements of the list using this comparator.
361      */
362     @SuppressWarnings("unchecked")
binarySearch(List<? extends T> list, T key, Comparator<? super T> c)363     public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c) {
364         if (c==null)
365             return binarySearch((List<? extends Comparable<? super T>>) list, key);
366 
367         if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
368             return Collections.indexedBinarySearch(list, key, c);
369         else
370             return Collections.iteratorBinarySearch(list, key, c);
371     }
372 
indexedBinarySearch(List<? extends T> l, T key, Comparator<? super T> c)373     private static <T> int indexedBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) {
374         int low = 0;
375         int high = l.size()-1;
376 
377         while (low <= high) {
378             int mid = (low + high) >>> 1;
379             T midVal = l.get(mid);
380             int cmp = c.compare(midVal, key);
381 
382             if (cmp < 0)
383                 low = mid + 1;
384             else if (cmp > 0)
385                 high = mid - 1;
386             else
387                 return mid; // key found
388         }
389         return -(low + 1);  // key not found
390     }
391 
iteratorBinarySearch(List<? extends T> l, T key, Comparator<? super T> c)392     private static <T> int iteratorBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) {
393         int low = 0;
394         int high = l.size()-1;
395         ListIterator<? extends T> i = l.listIterator();
396 
397         while (low <= high) {
398             int mid = (low + high) >>> 1;
399             T midVal = get(i, mid);
400             int cmp = c.compare(midVal, key);
401 
402             if (cmp < 0)
403                 low = mid + 1;
404             else if (cmp > 0)
405                 high = mid - 1;
406             else
407                 return mid; // key found
408         }
409         return -(low + 1);  // key not found
410     }
411 
412     /**
413      * Reverses the order of the elements in the specified list.<p>
414      *
415      * This method runs in linear time.
416      *
417      * @apiNote
418      * This method mutates the specified list in-place. To obtain a
419      * reverse-ordered view of a list without mutating it, use the
420      * {@link List#reversed List.reversed} method.
421      *
422      * @param  list the list whose elements are to be reversed.
423      * @throws UnsupportedOperationException if the specified list or
424      *         its list-iterator does not support the {@code set} operation.
425      * @see    List#reversed List.reversed
426      */
427     @SuppressWarnings({"rawtypes", "unchecked"})
reverse(List<?> list)428     public static void reverse(List<?> list) {
429         int size = list.size();
430         if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) {
431             for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--)
432                 swap(list, i, j);
433         } else {
434             // instead of using a raw type here, it's possible to capture
435             // the wildcard but it will require a call to a supplementary
436             // private method
437             ListIterator fwd = list.listIterator();
438             ListIterator rev = list.listIterator(size);
439             for (int i=0, mid=list.size()>>1; i<mid; i++) {
440                 Object tmp = fwd.next();
441                 fwd.set(rev.previous());
442                 rev.set(tmp);
443             }
444         }
445     }
446 
447     /**
448      * Randomly permutes the specified list using a default source of
449      * randomness.  All permutations occur with approximately equal
450      * likelihood.
451      *
452      * <p>The hedge "approximately" is used in the foregoing description because
453      * default source of randomness is only approximately an unbiased source
454      * of independently chosen bits. If it were a perfect source of randomly
455      * chosen bits, then the algorithm would choose permutations with perfect
456      * uniformity.
457      *
458      * <p>This implementation traverses the list backwards, from the last
459      * element up to the second, repeatedly swapping a randomly selected element
460      * into the "current position".  Elements are randomly selected from the
461      * portion of the list that runs from the first element to the current
462      * position, inclusive.
463      *
464      * @implSpec This method runs in linear time.  If the specified list does
465      * not implement the {@link RandomAccess} interface and is large, this
466      * implementation dumps the specified list into an array before shuffling
467      * it, and dumps the shuffled array back into the list.  This avoids the
468      * quadratic behavior that would result from shuffling a "sequential
469      * access" list in place.
470      *
471      * @param  list the list to be shuffled.
472      * @throws UnsupportedOperationException if the specified list or
473      *         its list-iterator does not support the {@code set} operation.
474      */
shuffle(List<?> list)475     public static void shuffle(List<?> list) {
476         Random rnd = r;
477         if (rnd == null)
478             r = rnd = new Random(); // harmless race.
479         shuffle(list, rnd);
480     }
481 
482     private static Random r;
483 
484     /**
485      * Randomly permute the specified list using the specified source of
486      * randomness.<p>
487      *
488      * This method is equivalent to {@link #shuffle(List, RandomGenerator)}
489      * and exists for backward compatibility. The {@link #shuffle(List, RandomGenerator)}
490      * method is preferred, as it is not limited to random generators
491      * that extend the {@link Random} class.
492      *
493      * @param  list the list to be shuffled.
494      * @param  rnd the source of randomness to use to shuffle the list.
495      * @throws UnsupportedOperationException if the specified list or its
496      *         list-iterator does not support the {@code set} operation.
497      */
shuffle(List<?> list, Random rnd)498     public static void shuffle(List<?> list, Random rnd) {
499         shuffle(list, (RandomGenerator) rnd);
500     }
501 
502     /**
503      * Randomly permute the specified list using the specified source of
504      * randomness.  All permutations occur with equal likelihood
505      * assuming that the source of randomness is fair.<p>
506      *
507      * This implementation traverses the list backwards, from the last element
508      * up to the second, repeatedly swapping a randomly selected element into
509      * the "current position".  Elements are randomly selected from the
510      * portion of the list that runs from the first element to the current
511      * position, inclusive.
512      *
513      * @implSpec This method runs in linear time.  If the specified list does
514      * not implement the {@link RandomAccess} interface and is large, this
515      * implementation dumps the specified list into an array before shuffling
516      * it, and dumps the shuffled array back into the list.  This avoids the
517      * quadratic behavior that would result from shuffling a "sequential
518      * access" list in place.
519      *
520      * @param  list the list to be shuffled.
521      * @param  rnd the source of randomness to use to shuffle the list.
522      * @throws UnsupportedOperationException if the specified list or its
523      *         list-iterator does not support the {@code set} operation.
524      * @since 21
525      */
526     @SuppressWarnings({"rawtypes", "unchecked"})
shuffle(List<?> list, RandomGenerator rnd)527     public static void shuffle(List<?> list, RandomGenerator rnd) {
528         int size = list.size();
529         if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
530             for (int i=size; i>1; i--)
531                 swap(list, i-1, rnd.nextInt(i));
532         } else {
533             Object[] arr = list.toArray();
534 
535             // Shuffle array
536             for (int i=size; i>1; i--)
537                 swap(arr, i-1, rnd.nextInt(i));
538 
539             // Dump array back into list
540             // instead of using a raw type here, it's possible to capture
541             // the wildcard but it will require a call to a supplementary
542             // private method
543             ListIterator it = list.listIterator();
544             for (Object e : arr) {
545                 it.next();
546                 it.set(e);
547             }
548         }
549     }
550 
551     /**
552      * Swaps the elements at the specified positions in the specified list.
553      * (If the specified positions are equal, invoking this method leaves
554      * the list unchanged.)
555      *
556      * @param list The list in which to swap elements.
557      * @param i the index of one element to be swapped.
558      * @param j the index of the other element to be swapped.
559      * @throws IndexOutOfBoundsException if either {@code i} or {@code j}
560      *         is out of range (i &lt; 0 || i &gt;= list.size()
561      *         || j &lt; 0 || j &gt;= list.size()).
562      * @since 1.4
563      */
564     @SuppressWarnings({"rawtypes", "unchecked"})
swap(List<?> list, int i, int j)565     public static void swap(List<?> list, int i, int j) {
566         // instead of using a raw type here, it's possible to capture
567         // the wildcard but it will require a call to a supplementary
568         // private method
569         final List l = list;
570         l.set(i, l.set(j, l.get(i)));
571     }
572 
573     /**
574      * Swaps the two specified elements in the specified array.
575      */
swap(Object[] arr, int i, int j)576     private static void swap(Object[] arr, int i, int j) {
577         Object tmp = arr[i];
578         arr[i] = arr[j];
579         arr[j] = tmp;
580     }
581 
582     /**
583      * Replaces all of the elements of the specified list with the specified
584      * element. <p>
585      *
586      * This method runs in linear time.
587      *
588      * @param  <T> the class of the objects in the list
589      * @param  list the list to be filled with the specified element.
590      * @param  obj The element with which to fill the specified list.
591      * @throws UnsupportedOperationException if the specified list or its
592      *         list-iterator does not support the {@code set} operation.
593      */
fill(List<? super T> list, T obj)594     public static <T> void fill(List<? super T> list, T obj) {
595         int size = list.size();
596 
597         if (size < FILL_THRESHOLD || list instanceof RandomAccess) {
598             for (int i=0; i<size; i++)
599                 list.set(i, obj);
600         } else {
601             ListIterator<? super T> itr = list.listIterator();
602             for (int i=0; i<size; i++) {
603                 itr.next();
604                 itr.set(obj);
605             }
606         }
607     }
608 
609     /**
610      * Copies all of the elements from one list into another.  After the
611      * operation, the index of each copied element in the destination list
612      * will be identical to its index in the source list.  The destination
613      * list's size must be greater than or equal to the source list's size.
614      * If it is greater, the remaining elements in the destination list are
615      * unaffected. <p>
616      *
617      * This method runs in linear time.
618      *
619      * @param  <T> the class of the objects in the lists
620      * @param  dest The destination list.
621      * @param  src The source list.
622      * @throws IndexOutOfBoundsException if the destination list is too small
623      *         to contain the entire source List.
624      * @throws UnsupportedOperationException if the destination list's
625      *         list-iterator does not support the {@code set} operation.
626      */
copy(List<? super T> dest, List<? extends T> src)627     public static <T> void copy(List<? super T> dest, List<? extends T> src) {
628         int srcSize = src.size();
629         if (srcSize > dest.size())
630             throw new IndexOutOfBoundsException("Source does not fit in dest");
631 
632         if (srcSize < COPY_THRESHOLD ||
633             (src instanceof RandomAccess && dest instanceof RandomAccess)) {
634             for (int i=0; i<srcSize; i++)
635                 dest.set(i, src.get(i));
636         } else {
637             ListIterator<? super T> di=dest.listIterator();
638             ListIterator<? extends T> si=src.listIterator();
639             for (int i=0; i<srcSize; i++) {
640                 di.next();
641                 di.set(si.next());
642             }
643         }
644     }
645 
646     /**
647      * Returns the minimum element of the given collection, according to the
648      * <i>natural ordering</i> of its elements.  All elements in the
649      * collection must implement the {@code Comparable} interface.
650      * Furthermore, all elements in the collection must be <i>mutually
651      * comparable</i> (that is, {@code e1.compareTo(e2)} must not throw a
652      * {@code ClassCastException} for any elements {@code e1} and
653      * {@code e2} in the collection).<p>
654      *
655      * This method iterates over the entire collection, hence it requires
656      * time proportional to the size of the collection.
657      *
658      * @param  <T> the class of the objects in the collection
659      * @param  coll the collection whose minimum element is to be determined.
660      * @return the minimum element of the given collection, according
661      *         to the <i>natural ordering</i> of its elements.
662      * @throws ClassCastException if the collection contains elements that are
663      *         not <i>mutually comparable</i> (for example, strings and
664      *         integers).
665      * @throws NoSuchElementException if the collection is empty.
666      * @see Comparable
667      */
min(Collection<? extends T> coll)668     public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) {
669         Iterator<? extends T> i = coll.iterator();
670         T candidate = i.next();
671 
672         while (i.hasNext()) {
673             T next = i.next();
674             if (next.compareTo(candidate) < 0)
675                 candidate = next;
676         }
677         return candidate;
678     }
679 
680     /**
681      * Returns the minimum element of the given collection, according to the
682      * order induced by the specified comparator.  All elements in the
683      * collection must be <i>mutually comparable</i> by the specified
684      * comparator (that is, {@code comp.compare(e1, e2)} must not throw a
685      * {@code ClassCastException} for any elements {@code e1} and
686      * {@code e2} in the collection).<p>
687      *
688      * This method iterates over the entire collection, hence it requires
689      * time proportional to the size of the collection.
690      *
691      * @param  <T> the class of the objects in the collection
692      * @param  coll the collection whose minimum element is to be determined.
693      * @param  comp the comparator with which to determine the minimum element.
694      *         A {@code null} value indicates that the elements' <i>natural
695      *         ordering</i> should be used.
696      * @return the minimum element of the given collection, according
697      *         to the specified comparator.
698      * @throws ClassCastException if the collection contains elements that are
699      *         not <i>mutually comparable</i> using the specified comparator.
700      * @throws NoSuchElementException if the collection is empty.
701      * @see Comparable
702      */
703     @SuppressWarnings({"unchecked"})
min(Collection<? extends T> coll, Comparator<? super T> comp)704     public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp) {
705         if (comp==null)
706             return (T)min((Collection<Comparable<Object>>) coll);
707 
708         Iterator<? extends T> i = coll.iterator();
709         T candidate = i.next();
710 
711         while (i.hasNext()) {
712             T next = i.next();
713             if (comp.compare(next, candidate) < 0)
714                 candidate = next;
715         }
716         return candidate;
717     }
718 
719     /**
720      * Returns the maximum element of the given collection, according to the
721      * <i>natural ordering</i> of its elements.  All elements in the
722      * collection must implement the {@code Comparable} interface.
723      * Furthermore, all elements in the collection must be <i>mutually
724      * comparable</i> (that is, {@code e1.compareTo(e2)} must not throw a
725      * {@code ClassCastException} for any elements {@code e1} and
726      * {@code e2} in the collection).<p>
727      *
728      * This method iterates over the entire collection, hence it requires
729      * time proportional to the size of the collection.
730      *
731      * @param  <T> the class of the objects in the collection
732      * @param  coll the collection whose maximum element is to be determined.
733      * @return the maximum element of the given collection, according
734      *         to the <i>natural ordering</i> of its elements.
735      * @throws ClassCastException if the collection contains elements that are
736      *         not <i>mutually comparable</i> (for example, strings and
737      *         integers).
738      * @throws NoSuchElementException if the collection is empty.
739      * @see Comparable
740      */
max(Collection<? extends T> coll)741     public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
742         Iterator<? extends T> i = coll.iterator();
743         T candidate = i.next();
744 
745         while (i.hasNext()) {
746             T next = i.next();
747             if (next.compareTo(candidate) > 0)
748                 candidate = next;
749         }
750         return candidate;
751     }
752 
753     /**
754      * Returns the maximum element of the given collection, according to the
755      * order induced by the specified comparator.  All elements in the
756      * collection must be <i>mutually comparable</i> by the specified
757      * comparator (that is, {@code comp.compare(e1, e2)} must not throw a
758      * {@code ClassCastException} for any elements {@code e1} and
759      * {@code e2} in the collection).<p>
760      *
761      * This method iterates over the entire collection, hence it requires
762      * time proportional to the size of the collection.
763      *
764      * @param  <T> the class of the objects in the collection
765      * @param  coll the collection whose maximum element is to be determined.
766      * @param  comp the comparator with which to determine the maximum element.
767      *         A {@code null} value indicates that the elements' <i>natural
768      *        ordering</i> should be used.
769      * @return the maximum element of the given collection, according
770      *         to the specified comparator.
771      * @throws ClassCastException if the collection contains elements that are
772      *         not <i>mutually comparable</i> using the specified comparator.
773      * @throws NoSuchElementException if the collection is empty.
774      * @see Comparable
775      */
776     @SuppressWarnings({"unchecked"})
max(Collection<? extends T> coll, Comparator<? super T> comp)777     public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp) {
778         if (comp==null)
779             return (T)max((Collection<Comparable<Object>>) coll);
780 
781         Iterator<? extends T> i = coll.iterator();
782         T candidate = i.next();
783 
784         while (i.hasNext()) {
785             T next = i.next();
786             if (comp.compare(next, candidate) > 0)
787                 candidate = next;
788         }
789         return candidate;
790     }
791 
792     /**
793      * Rotates the elements in the specified list by the specified distance.
794      * After calling this method, the element at index {@code i} will be
795      * the element previously at index {@code (i - distance)} mod
796      * {@code list.size()}, for all values of {@code i} between {@code 0}
797      * and {@code list.size()-1}, inclusive.  (This method has no effect on
798      * the size of the list.)
799      *
800      * <p>For example, suppose {@code list} comprises{@code  [t, a, n, k, s]}.
801      * After invoking {@code Collections.rotate(list, 1)} (or
802      * {@code Collections.rotate(list, -4)}), {@code list} will comprise
803      * {@code [s, t, a, n, k]}.
804      *
805      * <p>Note that this method can usefully be applied to sublists to
806      * move one or more elements within a list while preserving the
807      * order of the remaining elements.  For example, the following idiom
808      * moves the element at index {@code j} forward to position
809      * {@code k} (which must be greater than or equal to {@code j}):
810      * <pre>
811      *     Collections.rotate(list.subList(j, k+1), -1);
812      * </pre>
813      * To make this concrete, suppose {@code list} comprises
814      * {@code [a, b, c, d, e]}.  To move the element at index {@code 1}
815      * ({@code b}) forward two positions, perform the following invocation:
816      * <pre>
817      *     Collections.rotate(l.subList(1, 4), -1);
818      * </pre>
819      * The resulting list is {@code [a, c, d, b, e]}.
820      *
821      * <p>To move more than one element forward, increase the absolute value
822      * of the rotation distance.  To move elements backward, use a positive
823      * shift distance.
824      *
825      * <p>If the specified list is small or implements the {@link
826      * RandomAccess} interface, this implementation exchanges the first
827      * element into the location it should go, and then repeatedly exchanges
828      * the displaced element into the location it should go until a displaced
829      * element is swapped into the first element.  If necessary, the process
830      * is repeated on the second and successive elements, until the rotation
831      * is complete.  If the specified list is large and doesn't implement the
832      * {@code RandomAccess} interface, this implementation breaks the
833      * list into two sublist views around index {@code -distance mod size}.
834      * Then the {@link #reverse(List)} method is invoked on each sublist view,
835      * and finally it is invoked on the entire list.  For a more complete
836      * description of both algorithms, see Section 2.3 of Jon Bentley's
837      * <i>Programming Pearls</i> (Addison-Wesley, 1986).
838      *
839      * @param list the list to be rotated.
840      * @param distance the distance to rotate the list.  There are no
841      *        constraints on this value; it may be zero, negative, or
842      *        greater than {@code list.size()}.
843      * @throws UnsupportedOperationException if the specified list or
844      *         its list-iterator does not support the {@code set} operation.
845      * @since 1.4
846      */
rotate(List<?> list, int distance)847     public static void rotate(List<?> list, int distance) {
848         if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD)
849             rotate1(list, distance);
850         else
851             rotate2(list, distance);
852     }
853 
rotate1(List<T> list, int distance)854     private static <T> void rotate1(List<T> list, int distance) {
855         int size = list.size();
856         if (size == 0)
857             return;
858         distance = distance % size;
859         if (distance < 0)
860             distance += size;
861         if (distance == 0)
862             return;
863 
864         for (int cycleStart = 0, nMoved = 0; nMoved != size; cycleStart++) {
865             T displaced = list.get(cycleStart);
866             int i = cycleStart;
867             do {
868                 i += distance;
869                 if (i >= size)
870                     i -= size;
871                 displaced = list.set(i, displaced);
872                 nMoved ++;
873             } while (i != cycleStart);
874         }
875     }
876 
rotate2(List<?> list, int distance)877     private static void rotate2(List<?> list, int distance) {
878         int size = list.size();
879         if (size == 0)
880             return;
881         int mid =  -distance % size;
882         if (mid < 0)
883             mid += size;
884         if (mid == 0)
885             return;
886 
887         reverse(list.subList(0, mid));
888         reverse(list.subList(mid, size));
889         reverse(list);
890     }
891 
892     /**
893      * Replaces all occurrences of one specified value in a list with another.
894      * More formally, replaces with {@code newVal} each element {@code e}
895      * in {@code list} such that
896      * {@code (oldVal==null ? e==null : oldVal.equals(e))}.
897      * (This method has no effect on the size of the list.)
898      *
899      * @param  <T> the class of the objects in the list
900      * @param list the list in which replacement is to occur.
901      * @param oldVal the old value to be replaced.
902      * @param newVal the new value with which {@code oldVal} is to be
903      *        replaced.
904      * @return {@code true} if {@code list} contained one or more elements
905      *         {@code e} such that
906      *         {@code (oldVal==null ?  e==null : oldVal.equals(e))}.
907      * @throws UnsupportedOperationException if the specified list or
908      *         its list-iterator does not support the {@code set} operation.
909      * @since  1.4
910      */
replaceAll(List<T> list, T oldVal, T newVal)911     public static <T> boolean replaceAll(List<T> list, T oldVal, T newVal) {
912         boolean result = false;
913         int size = list.size();
914         if (size < REPLACEALL_THRESHOLD || list instanceof RandomAccess) {
915             if (oldVal==null) {
916                 for (int i=0; i<size; i++) {
917                     if (list.get(i)==null) {
918                         list.set(i, newVal);
919                         result = true;
920                     }
921                 }
922             } else {
923                 for (int i=0; i<size; i++) {
924                     if (oldVal.equals(list.get(i))) {
925                         list.set(i, newVal);
926                         result = true;
927                     }
928                 }
929             }
930         } else {
931             ListIterator<T> itr=list.listIterator();
932             if (oldVal==null) {
933                 for (int i=0; i<size; i++) {
934                     if (itr.next()==null) {
935                         itr.set(newVal);
936                         result = true;
937                     }
938                 }
939             } else {
940                 for (int i=0; i<size; i++) {
941                     if (oldVal.equals(itr.next())) {
942                         itr.set(newVal);
943                         result = true;
944                     }
945                 }
946             }
947         }
948         return result;
949     }
950 
951     /**
952      * Returns the starting position of the first occurrence of the specified
953      * target list within the specified source list, or -1 if there is no
954      * such occurrence.  More formally, returns the lowest index {@code i}
955      * such that {@code source.subList(i, i+target.size()).equals(target)},
956      * or -1 if there is no such index.  (Returns -1 if
957      * {@code target.size() > source.size()})
958      *
959      * <p>This implementation uses the "brute force" technique of scanning
960      * over the source list, looking for a match with the target at each
961      * location in turn.
962      *
963      * @param source the list in which to search for the first occurrence
964      *        of {@code target}.
965      * @param target the list to search for as a subList of {@code source}.
966      * @return the starting position of the first occurrence of the specified
967      *         target list within the specified source list, or -1 if there
968      *         is no such occurrence.
969      * @since  1.4
970      */
indexOfSubList(List<?> source, List<?> target)971     public static int indexOfSubList(List<?> source, List<?> target) {
972         int sourceSize = source.size();
973         int targetSize = target.size();
974         int maxCandidate = sourceSize - targetSize;
975 
976         if (sourceSize < INDEXOFSUBLIST_THRESHOLD ||
977             (source instanceof RandomAccess&&target instanceof RandomAccess)) {
978         nextCand:
979             for (int candidate = 0; candidate <= maxCandidate; candidate++) {
980                 for (int i=0, j=candidate; i<targetSize; i++, j++)
981                     if (!eq(target.get(i), source.get(j)))
982                         continue nextCand;  // Element mismatch, try next cand
983                 return candidate;  // All elements of candidate matched target
984             }
985         } else {  // Iterator version of above algorithm
986             ListIterator<?> si = source.listIterator();
987         nextCand:
988             for (int candidate = 0; candidate <= maxCandidate; candidate++) {
989                 ListIterator<?> ti = target.listIterator();
990                 for (int i=0; i<targetSize; i++) {
991                     if (!eq(ti.next(), si.next())) {
992                         // Back up source iterator to next candidate
993                         for (int j=0; j<i; j++)
994                             si.previous();
995                         continue nextCand;
996                     }
997                 }
998                 return candidate;
999             }
1000         }
1001         return -1;  // No candidate matched the target
1002     }
1003 
1004     /**
1005      * Returns the starting position of the last occurrence of the specified
1006      * target list within the specified source list, or -1 if there is no such
1007      * occurrence.  More formally, returns the highest index {@code i}
1008      * such that {@code source.subList(i, i+target.size()).equals(target)},
1009      * or -1 if there is no such index.  (Returns -1 if
1010      * {@code target.size() > source.size()})
1011      *
1012      * <p>This implementation uses the "brute force" technique of iterating
1013      * over the source list, looking for a match with the target at each
1014      * location in turn.
1015      *
1016      * @param source the list in which to search for the last occurrence
1017      *        of {@code target}.
1018      * @param target the list to search for as a subList of {@code source}.
1019      * @return the starting position of the last occurrence of the specified
1020      *         target list within the specified source list, or -1 if there
1021      *         is no such occurrence.
1022      * @since  1.4
1023      */
lastIndexOfSubList(List<?> source, List<?> target)1024     public static int lastIndexOfSubList(List<?> source, List<?> target) {
1025         int sourceSize = source.size();
1026         int targetSize = target.size();
1027         int maxCandidate = sourceSize - targetSize;
1028 
1029         if (sourceSize < INDEXOFSUBLIST_THRESHOLD ||
1030             source instanceof RandomAccess) {   // Index access version
1031         nextCand:
1032             for (int candidate = maxCandidate; candidate >= 0; candidate--) {
1033                 for (int i=0, j=candidate; i<targetSize; i++, j++)
1034                     if (!eq(target.get(i), source.get(j)))
1035                         continue nextCand;  // Element mismatch, try next cand
1036                 return candidate;  // All elements of candidate matched target
1037             }
1038         } else {  // Iterator version of above algorithm
1039             if (maxCandidate < 0)
1040                 return -1;
1041             ListIterator<?> si = source.listIterator(maxCandidate);
1042         nextCand:
1043             for (int candidate = maxCandidate; candidate >= 0; candidate--) {
1044                 ListIterator<?> ti = target.listIterator();
1045                 for (int i=0; i<targetSize; i++) {
1046                     if (!eq(ti.next(), si.next())) {
1047                         if (candidate != 0) {
1048                             // Back up source iterator to next candidate
1049                             for (int j=0; j<=i+1; j++)
1050                                 si.previous();
1051                         }
1052                         continue nextCand;
1053                     }
1054                 }
1055                 return candidate;
1056             }
1057         }
1058         return -1;  // No candidate matched the target
1059     }
1060 
1061 
1062     // Unmodifiable Wrappers
1063 
1064     /**
1065      * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
1066      * specified collection. Query operations on the returned collection "read through"
1067      * to the specified collection, and attempts to modify the returned
1068      * collection, whether direct or via its iterator, result in an
1069      * {@code UnsupportedOperationException}.<p>
1070      *
1071      * The returned collection does <i>not</i> pass the hashCode and equals
1072      * operations through to the backing collection, but relies on
1073      * {@code Object}'s {@code equals} and {@code hashCode} methods.  This
1074      * is necessary to preserve the contracts of these operations in the case
1075      * that the backing collection is a set or a list.<p>
1076      *
1077      * The returned collection will be serializable if the specified collection
1078      * is serializable.
1079      *
1080      * @implNote This method may return its argument if the argument is already unmodifiable.
1081      * @param  <T> the class of the objects in the collection
1082      * @param  c the collection for which an unmodifiable view is to be
1083      *         returned.
1084      * @return an unmodifiable view of the specified collection.
1085      */
1086     @SuppressWarnings("unchecked")
unmodifiableCollection(Collection<? extends T> c)1087     public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
1088         if (c.getClass() == UnmodifiableCollection.class) {
1089             return (Collection<T>) c;
1090         }
1091         return new UnmodifiableCollection<>(c);
1092     }
1093 
1094     /**
1095      * @serial include
1096      */
1097     static class UnmodifiableCollection<E> implements Collection<E>, Serializable {
1098         @java.io.Serial
1099         private static final long serialVersionUID = 1820017752578914078L;
1100 
1101         @SuppressWarnings("serial") // Conditionally serializable
1102         final Collection<? extends E> c;
1103 
UnmodifiableCollection(Collection<? extends E> c)1104         UnmodifiableCollection(Collection<? extends E> c) {
1105             if (c==null)
1106                 throw new NullPointerException();
1107             this.c = c;
1108         }
1109 
size()1110         public int size()                          {return c.size();}
isEmpty()1111         public boolean isEmpty()                   {return c.isEmpty();}
contains(Object o)1112         public boolean contains(Object o)          {return c.contains(o);}
toArray()1113         public Object[] toArray()                  {return c.toArray();}
toArray(T[] a)1114         public <T> T[] toArray(T[] a)              {return c.toArray(a);}
toArray(IntFunction<T[]> f)1115         public <T> T[] toArray(IntFunction<T[]> f) {return c.toArray(f);}
toString()1116         public String toString()                   {return c.toString();}
1117 
iterator()1118         public Iterator<E> iterator() {
1119             return new Iterator<>() {
1120                 private final Iterator<? extends E> i = c.iterator();
1121 
1122                 public boolean hasNext() {return i.hasNext();}
1123                 public E next()          {return i.next();}
1124                 public void remove() {
1125                     throw new UnsupportedOperationException();
1126                 }
1127                 @Override
1128                 public void forEachRemaining(Consumer<? super E> action) {
1129                     // Use backing collection version
1130                     i.forEachRemaining(action);
1131                 }
1132             };
1133         }
1134 
add(E e)1135         public boolean add(E e) {
1136             throw new UnsupportedOperationException();
1137         }
remove(Object o)1138         public boolean remove(Object o) {
1139             throw new UnsupportedOperationException();
1140         }
1141 
containsAll(Collection<?> coll)1142         public boolean containsAll(Collection<?> coll) {
1143             return c.containsAll(coll);
1144         }
addAll(Collection<? extends E> coll)1145         public boolean addAll(Collection<? extends E> coll) {
1146             throw new UnsupportedOperationException();
1147         }
removeAll(Collection<?> coll)1148         public boolean removeAll(Collection<?> coll) {
1149             throw new UnsupportedOperationException();
1150         }
retainAll(Collection<?> coll)1151         public boolean retainAll(Collection<?> coll) {
1152             throw new UnsupportedOperationException();
1153         }
clear()1154         public void clear() {
1155             throw new UnsupportedOperationException();
1156         }
1157 
1158         // Override default methods in Collection
1159         @Override
forEach(Consumer<? super E> action)1160         public void forEach(Consumer<? super E> action) {
1161             c.forEach(action);
1162         }
1163         @Override
removeIf(Predicate<? super E> filter)1164         public boolean removeIf(Predicate<? super E> filter) {
1165             throw new UnsupportedOperationException();
1166         }
1167         @SuppressWarnings("unchecked")
1168         @Override
spliterator()1169         public Spliterator<E> spliterator() {
1170             return (Spliterator<E>)c.spliterator();
1171         }
1172         @SuppressWarnings("unchecked")
1173         @Override
stream()1174         public Stream<E> stream() {
1175             return (Stream<E>)c.stream();
1176         }
1177         @SuppressWarnings("unchecked")
1178         @Override
parallelStream()1179         public Stream<E> parallelStream() {
1180             return (Stream<E>)c.parallelStream();
1181         }
1182     }
1183 
1184     /**
1185      * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
1186      * specified {@code SequencedCollection}. Query operations on the returned collection
1187      * "read through" to the specified collection, and attempts to modify the returned
1188      * collection, whether direct or via its iterator, result in an
1189      * {@code UnsupportedOperationException}.<p>
1190      *
1191      * The returned collection does <i>not</i> pass the {@code hashCode} and
1192      * {@code equals} operations through to the backing collection, but relies on
1193      * {@code Object}'s {@code equals} and {@code hashCode} methods.  This
1194      * is necessary to preserve the contracts of these operations in the case
1195      * that the backing collection is a set or a list.<p>
1196      *
1197      * The returned collection will be serializable if the specified collection
1198      * is serializable.
1199      *
1200      * @implNote This method may return its argument if the argument is already unmodifiable.
1201      * @param  <T> the class of the objects in the collection
1202      * @param  c the collection for which an unmodifiable view is to be
1203      *         returned.
1204      * @return an unmodifiable view of the specified collection.
1205      * @since 21
1206      */
1207     @SuppressWarnings("unchecked")
unmodifiableSequencedCollection(SequencedCollection<? extends T> c)1208     public static <T> SequencedCollection<T> unmodifiableSequencedCollection(SequencedCollection<? extends T> c) {
1209         if (c.getClass() == UnmodifiableSequencedCollection.class) {
1210             return (SequencedCollection<T>) c;
1211         }
1212         return new UnmodifiableSequencedCollection<>(c);
1213     }
1214 
1215     /**
1216      * @serial include
1217      */
1218     static class UnmodifiableSequencedCollection<E> extends UnmodifiableCollection<E>
1219             implements SequencedCollection<E>, Serializable {
1220 
1221         @java.io.Serial
1222         private static final long serialVersionUID = -6060065079711684830L;
1223 
UnmodifiableSequencedCollection(SequencedCollection<? extends E> c)1224         UnmodifiableSequencedCollection(SequencedCollection<? extends E> c) {
1225             super(c);
1226         }
1227 
1228         @SuppressWarnings("unchecked")
sc()1229         private SequencedCollection<E> sc() {
1230             return (SequencedCollection<E>) c;
1231         }
1232 
1233         // Even though this wrapper class is serializable, the reversed view is effectively
1234         // not serializable because it points to the reversed collection view, which usually isn't
1235         // serializable.
reversed()1236         public SequencedCollection<E> reversed() {
1237             return new UnmodifiableSequencedCollection<>(sc().reversed());
1238         }
1239 
addFirst(E e)1240         public void addFirst(E e) {
1241             throw new UnsupportedOperationException();
1242         }
1243 
addLast(E e)1244         public void addLast(E e) {
1245             throw new UnsupportedOperationException();
1246         }
1247 
getFirst()1248         public E getFirst() {
1249             return sc().getFirst();
1250         }
1251 
getLast()1252         public E getLast() {
1253             return sc().getLast();
1254         }
1255 
removeFirst()1256         public E removeFirst() {
1257             throw new UnsupportedOperationException();
1258         }
1259 
removeLast()1260         public E removeLast() {
1261             throw new UnsupportedOperationException();
1262         }
1263     }
1264 
1265     /**
1266      * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
1267      * specified set. Query operations on the returned set "read through" to the specified
1268      * set, and attempts to modify the returned set, whether direct or via its
1269      * iterator, result in an {@code UnsupportedOperationException}.<p>
1270      *
1271      * The returned set will be serializable if the specified set
1272      * is serializable.
1273      *
1274      * @implNote This method may return its argument if the argument is already unmodifiable.
1275      * @param  <T> the class of the objects in the set
1276      * @param  s the set for which an unmodifiable view is to be returned.
1277      * @return an unmodifiable view of the specified set.
1278      */
1279     @SuppressWarnings("unchecked")
unmodifiableSet(Set<? extends T> s)1280     public static <T> Set<T> unmodifiableSet(Set<? extends T> s) {
1281         // Not checking for subclasses because of heap pollution and information leakage.
1282         if (s.getClass() == UnmodifiableSet.class) {
1283             return (Set<T>) s;
1284         }
1285         return new UnmodifiableSet<>(s);
1286     }
1287 
1288     /**
1289      * @serial include
1290      */
1291     static class UnmodifiableSet<E> extends UnmodifiableCollection<E>
1292                                  implements Set<E>, Serializable {
1293         @java.io.Serial
1294         private static final long serialVersionUID = -9215047833775013803L;
1295 
UnmodifiableSet(Set<? extends E> s)1296         UnmodifiableSet(Set<? extends E> s)     {super(s);}
equals(Object o)1297         public boolean equals(Object o) {return o == this || c.equals(o);}
hashCode()1298         public int hashCode()           {return c.hashCode();}
1299     }
1300 
1301     /**
1302      * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
1303      * specified {@code SequencedSet}. Query operations on the returned set
1304      * "read through" to the specified set, and attempts to modify the returned
1305      * set, whether direct or via its iterator, result in an
1306      * {@code UnsupportedOperationException}.<p>
1307      *
1308      * The returned set will be serializable if the specified set
1309      * is serializable.
1310      *
1311      * @implNote This method may return its argument if the argument is already unmodifiable.
1312      * @param  <T> the class of the objects in the set
1313      * @param  s the set for which an unmodifiable view is to be returned.
1314      * @return an unmodifiable view of the specified sequenced set.
1315      * @since 21
1316      */
1317     @SuppressWarnings("unchecked")
unmodifiableSequencedSet(SequencedSet<? extends T> s)1318     public static <T> SequencedSet<T> unmodifiableSequencedSet(SequencedSet<? extends T> s) {
1319         // Not checking for subclasses because of heap pollution and information leakage.
1320         if (s.getClass() == UnmodifiableSequencedSet.class) {
1321             return (SequencedSet<T>) s;
1322         }
1323         return new UnmodifiableSequencedSet<>(s);
1324     }
1325 
1326     /**
1327      * @serial include
1328      */
1329     static class UnmodifiableSequencedSet<E> extends UnmodifiableSequencedCollection<E>
1330                                              implements SequencedSet<E>, Serializable {
1331         @java.io.Serial
1332         private static final long serialVersionUID = -2153469532349793522L;
1333 
UnmodifiableSequencedSet(SequencedSet<? extends E> s)1334         UnmodifiableSequencedSet(SequencedSet<? extends E> s)    {super(s);}
equals(Object o)1335         public boolean equals(Object o)                          {return o == this || c.equals(o);}
hashCode()1336         public int hashCode()                                    {return c.hashCode();}
1337 
1338         @SuppressWarnings("unchecked")
ss()1339         private SequencedSet<E> ss() {
1340             return (SequencedSet<E>) c;
1341         }
1342 
1343         // Even though this wrapper class is serializable, the reversed view is effectively
1344         // not serializable because it points to the reversed set view, which usually isn't
1345         // serializable.
reversed()1346         public SequencedSet<E> reversed() {
1347             return new UnmodifiableSequencedSet<>(ss().reversed());
1348         }
1349     }
1350 
1351     /**
1352      * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
1353      * specified sorted set. Query operations on the returned sorted set "read
1354      * through" to the specified sorted set.  Attempts to modify the returned
1355      * sorted set, whether direct, via its iterator, or via its
1356      * {@code subSet}, {@code headSet}, or {@code tailSet} views, result in
1357      * an {@code UnsupportedOperationException}.<p>
1358      *
1359      * The returned sorted set will be serializable if the specified sorted set
1360      * is serializable.
1361      *
1362      * @implNote This method may return its argument if the argument is already unmodifiable.
1363      * @param  <T> the class of the objects in the set
1364      * @param s the sorted set for which an unmodifiable view is to be
1365      *        returned.
1366      * @return an unmodifiable view of the specified sorted set.
1367      */
unmodifiableSortedSet(SortedSet<T> s)1368     public static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s) {
1369         // Not checking for subclasses because of heap pollution and information leakage.
1370         if (s.getClass() == UnmodifiableSortedSet.class) {
1371             return s;
1372         }
1373         return new UnmodifiableSortedSet<>(s);
1374     }
1375 
1376     /**
1377      * @serial include
1378      */
1379     static class UnmodifiableSortedSet<E>
1380                              extends UnmodifiableSet<E>
1381                              implements SortedSet<E>, Serializable {
1382         @java.io.Serial
1383         private static final long serialVersionUID = -4929149591599911165L;
1384         @SuppressWarnings("serial") // Conditionally serializable
1385         private final SortedSet<E> ss;
1386 
UnmodifiableSortedSet(SortedSet<E> s)1387         UnmodifiableSortedSet(SortedSet<E> s) {super(s); ss = s;}
1388 
comparator()1389         public Comparator<? super E> comparator() {return ss.comparator();}
1390 
subSet(E fromElement, E toElement)1391         public SortedSet<E> subSet(E fromElement, E toElement) {
1392             return new UnmodifiableSortedSet<>(ss.subSet(fromElement,toElement));
1393         }
headSet(E toElement)1394         public SortedSet<E> headSet(E toElement) {
1395             return new UnmodifiableSortedSet<>(ss.headSet(toElement));
1396         }
tailSet(E fromElement)1397         public SortedSet<E> tailSet(E fromElement) {
1398             return new UnmodifiableSortedSet<>(ss.tailSet(fromElement));
1399         }
1400 
first()1401         public E first()                   {return ss.first();}
last()1402         public E last()                    {return ss.last();}
1403     }
1404 
1405     /**
1406      * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
1407      * specified navigable set. Query operations on the returned navigable set "read
1408      * through" to the specified navigable set.  Attempts to modify the returned
1409      * navigable set, whether direct, via its iterator, or via its
1410      * {@code subSet}, {@code headSet}, or {@code tailSet} views, result in
1411      * an {@code UnsupportedOperationException}.<p>
1412      *
1413      * The returned navigable set will be serializable if the specified
1414      * navigable set is serializable.
1415      *
1416      * @implNote This method may return its argument if the argument is already unmodifiable.
1417      * @param  <T> the class of the objects in the set
1418      * @param s the navigable set for which an unmodifiable view is to be
1419      *        returned
1420      * @return an unmodifiable view of the specified navigable set
1421      * @since 1.8
1422      */
unmodifiableNavigableSet(NavigableSet<T> s)1423     public static <T> NavigableSet<T> unmodifiableNavigableSet(NavigableSet<T> s) {
1424         if (s.getClass() == UnmodifiableNavigableSet.class) {
1425             return s;
1426         }
1427         return new UnmodifiableNavigableSet<>(s);
1428     }
1429 
1430     /**
1431      * Wraps a navigable set and disables all of the mutative operations.
1432      *
1433      * @param <E> type of elements
1434      * @serial include
1435      */
1436     static class UnmodifiableNavigableSet<E>
1437                              extends UnmodifiableSortedSet<E>
1438                              implements NavigableSet<E>, Serializable {
1439 
1440         @java.io.Serial
1441         private static final long serialVersionUID = -6027448201786391929L;
1442 
1443         /**
1444          * A singleton empty unmodifiable navigable set used for
1445          * {@link #emptyNavigableSet()}.
1446          *
1447          * @param <E> type of elements, if there were any, and bounds
1448          */
1449         private static class EmptyNavigableSet<E> extends UnmodifiableNavigableSet<E>
1450             implements Serializable {
1451             @java.io.Serial
1452             private static final long serialVersionUID = -6291252904449939134L;
1453 
EmptyNavigableSet()1454             public EmptyNavigableSet() {
1455                 super(new TreeSet<>());
1456             }
1457 
1458             @java.io.Serial
readResolve()1459             private Object readResolve()        { return EMPTY_NAVIGABLE_SET; }
1460         }
1461 
1462         private static final NavigableSet<?> EMPTY_NAVIGABLE_SET =
1463                 new EmptyNavigableSet<>();
1464 
1465         /**
1466          * The instance we are protecting.
1467          */
1468         @SuppressWarnings("serial") // Conditionally serializable
1469         private final NavigableSet<E> ns;
1470 
UnmodifiableNavigableSet(NavigableSet<E> s)1471         UnmodifiableNavigableSet(NavigableSet<E> s)         {super(s); ns = s;}
1472 
lower(E e)1473         public E lower(E e)                             { return ns.lower(e); }
floor(E e)1474         public E floor(E e)                             { return ns.floor(e); }
ceiling(E e)1475         public E ceiling(E e)                         { return ns.ceiling(e); }
higher(E e)1476         public E higher(E e)                           { return ns.higher(e); }
pollFirst()1477         public E pollFirst()     { throw new UnsupportedOperationException(); }
pollLast()1478         public E pollLast()      { throw new UnsupportedOperationException(); }
descendingSet()1479         public NavigableSet<E> descendingSet()
1480                  { return new UnmodifiableNavigableSet<>(ns.descendingSet()); }
descendingIterator()1481         public Iterator<E> descendingIterator()
1482                                          { return descendingSet().iterator(); }
1483 
subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive)1484         public NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
1485             return new UnmodifiableNavigableSet<>(
1486                 ns.subSet(fromElement, fromInclusive, toElement, toInclusive));
1487         }
1488 
headSet(E toElement, boolean inclusive)1489         public NavigableSet<E> headSet(E toElement, boolean inclusive) {
1490             return new UnmodifiableNavigableSet<>(
1491                 ns.headSet(toElement, inclusive));
1492         }
1493 
tailSet(E fromElement, boolean inclusive)1494         public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
1495             return new UnmodifiableNavigableSet<>(
1496                 ns.tailSet(fromElement, inclusive));
1497         }
1498     }
1499 
1500     /**
1501      * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
1502      * specified list. Query operations on the returned list "read through" to the
1503      * specified list, and attempts to modify the returned list, whether
1504      * direct or via its iterator, result in an
1505      * {@code UnsupportedOperationException}.<p>
1506      *
1507      * The returned list will be serializable if the specified list
1508      * is serializable. Similarly, the returned list will implement
1509      * {@link RandomAccess} if the specified list does.
1510      *
1511      * @implNote This method may return its argument if the argument is already unmodifiable.
1512      * @param  <T> the class of the objects in the list
1513      * @param  list the list for which an unmodifiable view is to be returned.
1514      * @return an unmodifiable view of the specified list.
1515      */
1516     @SuppressWarnings("unchecked")
unmodifiableList(List<? extends T> list)1517     public static <T> List<T> unmodifiableList(List<? extends T> list) {
1518         if (list.getClass() == UnmodifiableList.class || list.getClass() == UnmodifiableRandomAccessList.class) {
1519            return (List<T>) list;
1520         }
1521 
1522         return (list instanceof RandomAccess ?
1523                 new UnmodifiableRandomAccessList<>(list) :
1524                 new UnmodifiableList<>(list));
1525     }
1526 
1527     /**
1528      * @serial include
1529      */
1530     static class UnmodifiableList<E> extends UnmodifiableCollection<E>
1531                                   implements List<E> {
1532         @java.io.Serial
1533         private static final long serialVersionUID = -283967356065247728L;
1534 
1535         @SuppressWarnings("serial") // Conditionally serializable
1536         final List<? extends E> list;
1537 
UnmodifiableList(List<? extends E> list)1538         UnmodifiableList(List<? extends E> list) {
1539             super(list);
1540             this.list = list;
1541         }
1542 
equals(Object o)1543         public boolean equals(Object o) {return o == this || list.equals(o);}
hashCode()1544         public int hashCode()           {return list.hashCode();}
1545 
get(int index)1546         public E get(int index) {return list.get(index);}
set(int index, E element)1547         public E set(int index, E element) {
1548             throw new UnsupportedOperationException();
1549         }
add(int index, E element)1550         public void add(int index, E element) {
1551             throw new UnsupportedOperationException();
1552         }
remove(int index)1553         public E remove(int index) {
1554             throw new UnsupportedOperationException();
1555         }
indexOf(Object o)1556         public int indexOf(Object o)            {return list.indexOf(o);}
lastIndexOf(Object o)1557         public int lastIndexOf(Object o)        {return list.lastIndexOf(o);}
addAll(int index, Collection<? extends E> c)1558         public boolean addAll(int index, Collection<? extends E> c) {
1559             throw new UnsupportedOperationException();
1560         }
1561 
1562         @Override
replaceAll(UnaryOperator<E> operator)1563         public void replaceAll(UnaryOperator<E> operator) {
1564             throw new UnsupportedOperationException();
1565         }
1566         @Override
sort(Comparator<? super E> c)1567         public void sort(Comparator<? super E> c) {
1568             throw new UnsupportedOperationException();
1569         }
1570 
listIterator()1571         public ListIterator<E> listIterator()   {return listIterator(0);}
1572 
listIterator(final int index)1573         public ListIterator<E> listIterator(final int index) {
1574             return new ListIterator<>() {
1575                 private final ListIterator<? extends E> i
1576                     = list.listIterator(index);
1577 
1578                 public boolean hasNext()     {return i.hasNext();}
1579                 public E next()              {return i.next();}
1580                 public boolean hasPrevious() {return i.hasPrevious();}
1581                 public E previous()          {return i.previous();}
1582                 public int nextIndex()       {return i.nextIndex();}
1583                 public int previousIndex()   {return i.previousIndex();}
1584 
1585                 public void remove() {
1586                     throw new UnsupportedOperationException();
1587                 }
1588                 public void set(E e) {
1589                     throw new UnsupportedOperationException();
1590                 }
1591                 public void add(E e) {
1592                     throw new UnsupportedOperationException();
1593                 }
1594 
1595                 @Override
1596                 public void forEachRemaining(Consumer<? super E> action) {
1597                     i.forEachRemaining(action);
1598                 }
1599             };
1600         }
1601 
subList(int fromIndex, int toIndex)1602         public List<E> subList(int fromIndex, int toIndex) {
1603             return new UnmodifiableList<>(list.subList(fromIndex, toIndex));
1604         }
1605 
1606         /**
1607          * UnmodifiableRandomAccessList instances are serialized as
1608          * UnmodifiableList instances to allow them to be deserialized
1609          * in pre-1.4 JREs (which do not have UnmodifiableRandomAccessList).
1610          * This method inverts the transformation.  As a beneficial
1611          * side-effect, it also grafts the RandomAccess marker onto
1612          * UnmodifiableList instances that were serialized in pre-1.4 JREs.
1613          *
1614          * Note: Unfortunately, UnmodifiableRandomAccessList instances
1615          * serialized in 1.4.1 and deserialized in 1.4 will become
1616          * UnmodifiableList instances, as this method was missing in 1.4.
1617          */
1618         @java.io.Serial
readResolve()1619         private Object readResolve() {
1620             return (list instanceof RandomAccess
1621                     ? new UnmodifiableRandomAccessList<>(list)
1622                     : this);
1623         }
1624     }
1625 
1626     /**
1627      * @serial include
1628      */
1629     static class UnmodifiableRandomAccessList<E> extends UnmodifiableList<E>
1630                                               implements RandomAccess
1631     {
1632         UnmodifiableRandomAccessList(List<? extends E> list) {
1633             super(list);
1634         }
1635 
1636         public List<E> subList(int fromIndex, int toIndex) {
1637             return new UnmodifiableRandomAccessList<>(
1638                 list.subList(fromIndex, toIndex));
1639         }
1640 
1641         @java.io.Serial
1642         private static final long serialVersionUID = -2542308836966382001L;
1643 
1644         /**
1645          * Allows instances to be deserialized in pre-1.4 JREs (which do
1646          * not have UnmodifiableRandomAccessList).  UnmodifiableList has
1647          * a readResolve method that inverts this transformation upon
1648          * deserialization.
1649          */
1650         @java.io.Serial
1651         private Object writeReplace() {
1652             return new UnmodifiableList<>(list);
1653         }
1654     }
1655 
1656     /**
1657      * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
1658      * specified map. Query operations on the returned map "read through"
1659      * to the specified map, and attempts to modify the returned
1660      * map, whether direct or via its collection views, result in an
1661      * {@code UnsupportedOperationException}.<p>
1662      *
1663      * The returned map will be serializable if the specified map
1664      * is serializable.
1665      *
1666      * @implNote This method may return its argument if the argument is already unmodifiable.
1667      * @param <K> the class of the map keys
1668      * @param <V> the class of the map values
1669      * @param  m the map for which an unmodifiable view is to be returned.
1670      * @return an unmodifiable view of the specified map.
1671      */
1672     @SuppressWarnings("unchecked")
1673     public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> m) {
1674         // Not checking for subclasses because of heap pollution and information leakage.
1675         if (m.getClass() == UnmodifiableMap.class) {
1676             return (Map<K,V>) m;
1677         }
1678         return new UnmodifiableMap<>(m);
1679     }
1680 
1681     /**
1682      * @serial include
1683      */
1684     private static class UnmodifiableMap<K,V> implements Map<K,V>, Serializable {
1685         @java.io.Serial
1686         private static final long serialVersionUID = -1034234728574286014L;
1687 
1688         @SuppressWarnings("serial") // Conditionally serializable
1689         final Map<? extends K, ? extends V> m;
1690 
1691         UnmodifiableMap(Map<? extends K, ? extends V> m) {
1692             if (m==null)
1693                 throw new NullPointerException();
1694             this.m = m;
1695         }
1696 
1697         public int size()                        {return m.size();}
1698         public boolean isEmpty()                 {return m.isEmpty();}
1699         public boolean containsKey(Object key)   {return m.containsKey(key);}
1700         public boolean containsValue(Object val) {return m.containsValue(val);}
1701         public V get(Object key)                 {return m.get(key);}
1702 
1703         public V put(K key, V value) {
1704             throw new UnsupportedOperationException();
1705         }
1706         public V remove(Object key) {
1707             throw new UnsupportedOperationException();
1708         }
1709         public void putAll(Map<? extends K, ? extends V> m) {
1710             throw new UnsupportedOperationException();
1711         }
1712         public void clear() {
1713             throw new UnsupportedOperationException();
1714         }
1715 
1716         private transient Set<K> keySet;
1717         private transient Set<Map.Entry<K,V>> entrySet;
1718         private transient Collection<V> values;
1719 
1720         public Set<K> keySet() {
1721             if (keySet==null)
1722                 keySet = unmodifiableSet(m.keySet());
1723             return keySet;
1724         }
1725 
1726         public Set<Map.Entry<K,V>> entrySet() {
1727             if (entrySet==null)
1728                 entrySet = new UnmodifiableEntrySet<>(m.entrySet());
1729             return entrySet;
1730         }
1731 
1732         public Collection<V> values() {
1733             if (values==null)
1734                 values = unmodifiableCollection(m.values());
1735             return values;
1736         }
1737 
1738         public boolean equals(Object o) {return o == this || m.equals(o);}
1739         public int hashCode()           {return m.hashCode();}
1740         public String toString()        {return m.toString();}
1741 
1742         // Override default methods in Map
1743         @Override
1744         @SuppressWarnings("unchecked")
1745         public V getOrDefault(Object k, V defaultValue) {
1746             // Safe cast as we don't change the value
1747             return ((Map<K, V>)m).getOrDefault(k, defaultValue);
1748         }
1749 
1750         @Override
1751         public void forEach(BiConsumer<? super K, ? super V> action) {
1752             m.forEach(action);
1753         }
1754 
1755         @Override
1756         public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
1757             throw new UnsupportedOperationException();
1758         }
1759 
1760         @Override
1761         public V putIfAbsent(K key, V value) {
1762             throw new UnsupportedOperationException();
1763         }
1764 
1765         @Override
1766         public boolean remove(Object key, Object value) {
1767             throw new UnsupportedOperationException();
1768         }
1769 
1770         @Override
1771         public boolean replace(K key, V oldValue, V newValue) {
1772             throw new UnsupportedOperationException();
1773         }
1774 
1775         @Override
1776         public V replace(K key, V value) {
1777             throw new UnsupportedOperationException();
1778         }
1779 
1780         @Override
1781         public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
1782             throw new UnsupportedOperationException();
1783         }
1784 
1785         @Override
1786         public V computeIfPresent(K key,
1787                 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
1788             throw new UnsupportedOperationException();
1789         }
1790 
1791         @Override
1792         public V compute(K key,
1793                 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
1794             throw new UnsupportedOperationException();
1795         }
1796 
1797         @Override
1798         public V merge(K key, V value,
1799                 BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
1800             throw new UnsupportedOperationException();
1801         }
1802 
1803         /**
1804          * We need this class in addition to UnmodifiableSet as
1805          * Map.Entries themselves permit modification of the backing Map
1806          * via their setValue operation.  This class is subtle: there are
1807          * many possible attacks that must be thwarted.
1808          *
1809          * @serial include
1810          */
1811         static class UnmodifiableEntrySet<K,V>
1812             extends UnmodifiableSet<Map.Entry<K,V>> {
1813             @java.io.Serial
1814             private static final long serialVersionUID = 7854390611657943733L;
1815 
1816             @SuppressWarnings({"unchecked"})
1817             UnmodifiableEntrySet(Set<? extends Map.Entry<? extends K, ? extends V>> s) {
1818                 super((Set<Map.Entry<K, V>>)s);
1819             }
1820 
1821             static <K, V> Consumer<Map.Entry<? extends K, ? extends V>> entryConsumer(
1822                     Consumer<? super Entry<K, V>> action) {
1823                 return e -> action.accept(new UnmodifiableEntry<>(e));
1824             }
1825 
1826             public void forEach(Consumer<? super Entry<K, V>> action) {
1827                 Objects.requireNonNull(action);
1828                 c.forEach(entryConsumer(action));
1829             }
1830 
1831             static final class UnmodifiableEntrySetSpliterator<K, V>
1832                     implements Spliterator<Entry<K,V>> {
1833                 final Spliterator<Map.Entry<K, V>> s;
1834 
1835                 UnmodifiableEntrySetSpliterator(Spliterator<Entry<K, V>> s) {
1836                     this.s = s;
1837                 }
1838 
1839                 @Override
1840                 public boolean tryAdvance(Consumer<? super Entry<K, V>> action) {
1841                     Objects.requireNonNull(action);
1842                     return s.tryAdvance(entryConsumer(action));
1843                 }
1844 
1845                 @Override
1846                 public void forEachRemaining(Consumer<? super Entry<K, V>> action) {
1847                     Objects.requireNonNull(action);
1848                     s.forEachRemaining(entryConsumer(action));
1849                 }
1850 
1851                 @Override
1852                 public Spliterator<Entry<K, V>> trySplit() {
1853                     Spliterator<Entry<K, V>> split = s.trySplit();
1854                     return split == null
1855                            ? null
1856                            : new UnmodifiableEntrySetSpliterator<>(split);
1857                 }
1858 
1859                 @Override
1860                 public long estimateSize() {
1861                     return s.estimateSize();
1862                 }
1863 
1864                 @Override
1865                 public long getExactSizeIfKnown() {
1866                     return s.getExactSizeIfKnown();
1867                 }
1868 
1869                 @Override
1870                 public int characteristics() {
1871                     return s.characteristics();
1872                 }
1873 
1874                 @Override
1875                 public boolean hasCharacteristics(int characteristics) {
1876                     return s.hasCharacteristics(characteristics);
1877                 }
1878 
1879                 @Override
1880                 public Comparator<? super Entry<K, V>> getComparator() {
1881                     return s.getComparator();
1882                 }
1883             }
1884 
1885             @SuppressWarnings("unchecked")
1886             public Spliterator<Entry<K,V>> spliterator() {
1887                 return new UnmodifiableEntrySetSpliterator<>(
1888                         (Spliterator<Map.Entry<K, V>>) c.spliterator());
1889             }
1890 
1891             @Override
1892             public Stream<Entry<K,V>> stream() {
1893                 return StreamSupport.stream(spliterator(), false);
1894             }
1895 
1896             @Override
1897             public Stream<Entry<K,V>> parallelStream() {
1898                 return StreamSupport.stream(spliterator(), true);
1899             }
1900 
1901             public Iterator<Map.Entry<K,V>> iterator() {
1902                 return new Iterator<>() {
1903                     private final Iterator<? extends Map.Entry<? extends K, ? extends V>> i = c.iterator();
1904 
1905                     public boolean hasNext() {
1906                         return i.hasNext();
1907                     }
1908                     public Map.Entry<K,V> next() {
1909                         return new UnmodifiableEntry<>(i.next());
1910                     }
1911                     public void remove() {
1912                         throw new UnsupportedOperationException();
1913                     }
1914                     // Seems like an oversight. http://b/110351017
1915                     public void forEachRemaining(Consumer<? super Map.Entry<K, V>> action) {
1916                         Objects.requireNonNull(action);
1917                         i.forEachRemaining(entryConsumer(action));
1918                     }
1919                 };
1920             }
1921 
1922             @SuppressWarnings("unchecked")
1923             public Object[] toArray() {
1924                 Object[] a = c.toArray();
1925                 for (int i=0; i<a.length; i++)
1926                     a[i] = new UnmodifiableEntry<>((Map.Entry<? extends K, ? extends V>)a[i]);
1927                 return a;
1928             }
1929 
1930             @SuppressWarnings("unchecked")
1931             public <T> T[] toArray(T[] a) {
1932                 // We don't pass a to c.toArray, to avoid window of
1933                 // vulnerability wherein an unscrupulous multithreaded client
1934                 // could get his hands on raw (unwrapped) Entries from c.
1935                 Object[] arr = c.toArray(a.length==0 ? a : Arrays.copyOf(a, 0));
1936 
1937                 for (int i=0; i<arr.length; i++)
1938                     arr[i] = new UnmodifiableEntry<>((Map.Entry<? extends K, ? extends V>)arr[i]);
1939 
1940                 if (arr.length > a.length)
1941                     return (T[])arr;
1942 
1943                 System.arraycopy(arr, 0, a, 0, arr.length);
1944                 if (a.length > arr.length)
1945                     a[arr.length] = null;
1946                 return a;
1947             }
1948 
1949             /**
1950              * This method is overridden to protect the backing set against
1951              * an object with a nefarious equals function that senses
1952              * that the equality-candidate is Map.Entry and calls its
1953              * setValue method.
1954              */
1955             public boolean contains(Object o) {
1956                 if (!(o instanceof Map.Entry))
1957                     return false;
1958                 return c.contains(
1959                     new UnmodifiableEntry<>((Map.Entry<?,?>) o));
1960             }
1961 
1962             /**
1963              * The next two methods are overridden to protect against
1964              * an unscrupulous List whose contains(Object o) method senses
1965              * when o is a Map.Entry, and calls o.setValue.
1966              */
1967             public boolean containsAll(Collection<?> coll) {
1968                 for (Object e : coll) {
1969                     if (!contains(e)) // Invokes safe contains() above
1970                         return false;
1971                 }
1972                 return true;
1973             }
1974             public boolean equals(Object o) {
1975                 if (o == this)
1976                     return true;
1977 
1978                 // Android-changed: (b/247094511) instanceof pattern variable is not yet supported.
1979                 /*
1980                 return o instanceof Set<?> s
1981                         && s.size() == c.size()
1982                         && containsAll(s); // Invokes safe containsAll() above
1983                  */
1984                 if (!(o instanceof Set))
1985                     return false;
1986                 Set<?> s = (Set<?>) o;
1987                 if (s.size() != c.size())
1988                     return false;
1989                 return containsAll(s); // Invokes safe containsAll() above
1990             }
1991 
1992             /**
1993              * This "wrapper class" serves two purposes: it prevents
1994              * the client from modifying the backing Map, by short-circuiting
1995              * the setValue method, and it protects the backing Map against
1996              * an ill-behaved Map.Entry that attempts to modify another
1997              * Map Entry when asked to perform an equality check.
1998              */
1999             private static class UnmodifiableEntry<K,V> implements Map.Entry<K,V> {
2000                 private Map.Entry<? extends K, ? extends V> e;
2001 
2002                 UnmodifiableEntry(Map.Entry<? extends K, ? extends V> e)
2003                         {this.e = Objects.requireNonNull(e);}
2004 
2005                 public K getKey()        {return e.getKey();}
2006                 public V getValue()      {return e.getValue();}
2007                 public V setValue(V value) {
2008                     throw new UnsupportedOperationException();
2009                 }
2010                 public int hashCode()    {return e.hashCode();}
2011                 public boolean equals(Object o) {
2012                     if (this == o)
2013                         return true;
2014                     // Android-changed: (b/247094511) instanceof pattern variable is not yet
2015                     // supported.
2016                     /*
2017                     return o instanceof Map.Entry<?, ?> t
2018                             && eq(e.getKey(),   t.getKey())
2019                             && eq(e.getValue(), t.getValue());
2020                     */
2021                     if (!(o instanceof Map.Entry))
2022                         return false;
2023                     Map.Entry<?,?> t = (Map.Entry<?,?>)o;
2024                     return eq(e.getKey(),   t.getKey()) &&
2025                             eq(e.getValue(), t.getValue());
2026                 }
2027                 public String toString() {return e.toString();}
2028             }
2029         }
2030     }
2031 
2032     /**
2033      * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
2034      * specified {@code SequencedMap}. Query operations on the returned map
2035      * "read through" to the specified map, and attempts to modify the returned
2036      * map, whether direct or via its collection views, result in an
2037      * {@code UnsupportedOperationException}.<p>
2038      *
2039      * The returned map will be serializable if the specified map
2040      * is serializable.
2041      *
2042      * @implNote This method may return its argument if the argument is already unmodifiable.
2043      * @param <K> the class of the map keys
2044      * @param <V> the class of the map values
2045      * @param  m the map for which an unmodifiable view is to be returned.
2046      * @return an unmodifiable view of the specified map.
2047      * @since 21
2048      */
2049     @SuppressWarnings("unchecked")
2050     public static <K,V> SequencedMap<K,V> unmodifiableSequencedMap(SequencedMap<? extends K, ? extends V> m) {
2051         // Not checking for subclasses because of heap pollution and information leakage.
2052         if (m.getClass() == UnmodifiableSequencedMap.class) {
2053             return (SequencedMap<K,V>) m;
2054         }
2055         return new UnmodifiableSequencedMap<>(m);
2056     }
2057 
2058     /**
2059      * @serial include
2060      */
2061     private static class UnmodifiableSequencedMap<K,V> extends UnmodifiableMap<K,V> implements SequencedMap<K,V>, Serializable {
2062         @java.io.Serial
2063         private static final long serialVersionUID = -8171676257373950636L;
2064 
2065         UnmodifiableSequencedMap(Map<? extends K, ? extends V> m) {
2066             super(m);
2067         }
2068 
2069         @SuppressWarnings("unchecked")
2070         private SequencedMap<K, V> sm() {
2071             return (SequencedMap<K, V>) m;
2072         }
2073 
2074         // Even though this wrapper class is serializable, the reversed view is effectively
2075         // not serializable because it points to the reversed map view, which usually isn't
2076         // serializable.
2077         public SequencedMap<K, V> reversed() {
2078             return new UnmodifiableSequencedMap<>(sm().reversed());
2079         }
2080 
2081         public Entry<K, V> pollFirstEntry() {
2082             throw new UnsupportedOperationException();
2083         }
2084 
2085         public Entry<K, V> pollLastEntry() {
2086             throw new UnsupportedOperationException();
2087         }
2088 
2089         public V putFirst(K k, V v) {
2090             throw new UnsupportedOperationException();
2091         }
2092 
2093         public V putLast(K k, V v) {
2094             throw new UnsupportedOperationException();
2095         }
2096     }
2097 
2098     /**
2099      * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
2100      * specified sorted map. Query operations on the returned sorted map "read through"
2101      * to the specified sorted map.  Attempts to modify the returned
2102      * sorted map, whether direct, via its collection views, or via its
2103      * {@code subMap}, {@code headMap}, or {@code tailMap} views, result in
2104      * an {@code UnsupportedOperationException}.<p>
2105      *
2106      * The returned sorted map will be serializable if the specified sorted map
2107      * is serializable.
2108      *
2109      * @implNote This method may return its argument if the argument is already unmodifiable.
2110      * @param <K> the class of the map keys
2111      * @param <V> the class of the map values
2112      * @param m the sorted map for which an unmodifiable view is to be
2113      *        returned.
2114      * @return an unmodifiable view of the specified sorted map.
2115      */
2116     @SuppressWarnings("unchecked")
2117     public static <K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K, ? extends V> m) {
2118         // Not checking for subclasses because of heap pollution and information leakage.
2119         if (m.getClass() == UnmodifiableSortedMap.class) {
2120             return (SortedMap<K,V>) m;
2121         }
2122         return new UnmodifiableSortedMap<>(m);
2123     }
2124 
2125     /**
2126      * @serial include
2127      */
2128     static class UnmodifiableSortedMap<K,V>
2129           extends UnmodifiableMap<K,V>
2130           implements SortedMap<K,V>, Serializable {
2131         @java.io.Serial
2132         private static final long serialVersionUID = -8806743815996713206L;
2133 
2134         @SuppressWarnings("serial") // Conditionally serializable
2135         private final SortedMap<K, ? extends V> sm;
2136 
2137         UnmodifiableSortedMap(SortedMap<K, ? extends V> m) {super(m); sm = m; }
2138         public Comparator<? super K> comparator()   { return sm.comparator(); }
2139         public SortedMap<K,V> subMap(K fromKey, K toKey)
2140              { return new UnmodifiableSortedMap<>(sm.subMap(fromKey, toKey)); }
2141         public SortedMap<K,V> headMap(K toKey)
2142                      { return new UnmodifiableSortedMap<>(sm.headMap(toKey)); }
2143         public SortedMap<K,V> tailMap(K fromKey)
2144                    { return new UnmodifiableSortedMap<>(sm.tailMap(fromKey)); }
2145         public K firstKey()                           { return sm.firstKey(); }
2146         public K lastKey()                             { return sm.lastKey(); }
2147     }
2148 
2149     /**
2150      * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
2151      * specified navigable map. Query operations on the returned navigable map "read
2152      * through" to the specified navigable map.  Attempts to modify the returned
2153      * navigable map, whether direct, via its collection views, or via its
2154      * {@code subMap}, {@code headMap}, or {@code tailMap} views, result in
2155      * an {@code UnsupportedOperationException}.<p>
2156      *
2157      * The returned navigable map will be serializable if the specified
2158      * navigable map is serializable.
2159      *
2160      * @implNote This method may return its argument if the argument is already unmodifiable.
2161      * @param <K> the class of the map keys
2162      * @param <V> the class of the map values
2163      * @param m the navigable map for which an unmodifiable view is to be
2164      *        returned
2165      * @return an unmodifiable view of the specified navigable map
2166      * @since 1.8
2167      */
2168     @SuppressWarnings("unchecked")
2169     public static <K,V> NavigableMap<K,V> unmodifiableNavigableMap(NavigableMap<K, ? extends V> m) {
2170         if (m.getClass() == UnmodifiableNavigableMap.class) {
2171             return (NavigableMap<K,V>) m;
2172         }
2173         return new UnmodifiableNavigableMap<>(m);
2174     }
2175 
2176     /**
2177      * @serial include
2178      */
2179     static class UnmodifiableNavigableMap<K,V>
2180           extends UnmodifiableSortedMap<K,V>
2181           implements NavigableMap<K,V>, Serializable {
2182         @java.io.Serial
2183         private static final long serialVersionUID = -4858195264774772197L;
2184 
2185         /**
2186          * A class for the {@link #EMPTY_NAVIGABLE_MAP} which needs readResolve
2187          * to preserve singleton property.
2188          *
2189          * @param <K> type of keys, if there were any, and of bounds
2190          * @param <V> type of values, if there were any
2191          */
2192         private static class EmptyNavigableMap<K,V> extends UnmodifiableNavigableMap<K,V>
2193             implements Serializable {
2194 
2195             @java.io.Serial
2196             private static final long serialVersionUID = -2239321462712562324L;
2197 
2198             EmptyNavigableMap()                       { super(new TreeMap<>()); }
2199 
2200             @Override
2201             public NavigableSet<K> navigableKeySet()
2202                                                 { return emptyNavigableSet(); }
2203 
2204             @java.io.Serial
2205             private Object readResolve()        { return EMPTY_NAVIGABLE_MAP; }
2206         }
2207 
2208         /**
2209          * Singleton for {@link #emptyNavigableMap()} which is also immutable.
2210          */
2211         private static final EmptyNavigableMap<?,?> EMPTY_NAVIGABLE_MAP =
2212             new EmptyNavigableMap<>();
2213 
2214         /**
2215          * The instance we wrap and protect.
2216          */
2217         @SuppressWarnings("serial") // Conditionally serializable
2218         private final NavigableMap<K, ? extends V> nm;
2219 
2220         UnmodifiableNavigableMap(NavigableMap<K, ? extends V> m)
2221                                                             {super(m); nm = m;}
2222 
2223         public K lowerKey(K key)                   { return nm.lowerKey(key); }
2224         public K floorKey(K key)                   { return nm.floorKey(key); }
2225         public K ceilingKey(K key)               { return nm.ceilingKey(key); }
2226         public K higherKey(K key)                 { return nm.higherKey(key); }
2227 
2228         @SuppressWarnings("unchecked")
2229         public Entry<K, V> lowerEntry(K key) {
2230             Entry<K,V> lower = (Entry<K, V>) nm.lowerEntry(key);
2231             return (null != lower)
2232                 ? new UnmodifiableEntrySet.UnmodifiableEntry<>(lower)
2233                 : null;
2234         }
2235 
2236         @SuppressWarnings("unchecked")
2237         public Entry<K, V> floorEntry(K key) {
2238             Entry<K,V> floor = (Entry<K, V>) nm.floorEntry(key);
2239             return (null != floor)
2240                 ? new UnmodifiableEntrySet.UnmodifiableEntry<>(floor)
2241                 : null;
2242         }
2243 
2244         @SuppressWarnings("unchecked")
2245         public Entry<K, V> ceilingEntry(K key) {
2246             Entry<K,V> ceiling = (Entry<K, V>) nm.ceilingEntry(key);
2247             return (null != ceiling)
2248                 ? new UnmodifiableEntrySet.UnmodifiableEntry<>(ceiling)
2249                 : null;
2250         }
2251 
2252 
2253         @SuppressWarnings("unchecked")
2254         public Entry<K, V> higherEntry(K key) {
2255             Entry<K,V> higher = (Entry<K, V>) nm.higherEntry(key);
2256             return (null != higher)
2257                 ? new UnmodifiableEntrySet.UnmodifiableEntry<>(higher)
2258                 : null;
2259         }
2260 
2261         @SuppressWarnings("unchecked")
2262         public Entry<K, V> firstEntry() {
2263             Entry<K,V> first = (Entry<K, V>) nm.firstEntry();
2264             return (null != first)
2265                 ? new UnmodifiableEntrySet.UnmodifiableEntry<>(first)
2266                 : null;
2267         }
2268 
2269         @SuppressWarnings("unchecked")
2270         public Entry<K, V> lastEntry() {
2271             Entry<K,V> last = (Entry<K, V>) nm.lastEntry();
2272             return (null != last)
2273                 ? new UnmodifiableEntrySet.UnmodifiableEntry<>(last)
2274                 : null;
2275         }
2276 
2277         public Entry<K, V> pollFirstEntry()
2278                                  { throw new UnsupportedOperationException(); }
2279         public Entry<K, V> pollLastEntry()
2280                                  { throw new UnsupportedOperationException(); }
2281         public NavigableMap<K, V> descendingMap()
2282                        { return unmodifiableNavigableMap(nm.descendingMap()); }
2283         public NavigableSet<K> navigableKeySet()
2284                      { return unmodifiableNavigableSet(nm.navigableKeySet()); }
2285         public NavigableSet<K> descendingKeySet()
2286                     { return unmodifiableNavigableSet(nm.descendingKeySet()); }
2287 
2288         public NavigableMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
2289             return unmodifiableNavigableMap(
2290                 nm.subMap(fromKey, fromInclusive, toKey, toInclusive));
2291         }
2292 
2293         public NavigableMap<K, V> headMap(K toKey, boolean inclusive)
2294              { return unmodifiableNavigableMap(nm.headMap(toKey, inclusive)); }
2295         public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive)
2296            { return unmodifiableNavigableMap(nm.tailMap(fromKey, inclusive)); }
2297     }
2298 
2299     // Synch Wrappers
2300 
2301     /**
2302      * Returns a synchronized (thread-safe) collection backed by the specified
2303      * collection.  In order to guarantee serial access, it is critical that
2304      * <strong>all</strong> access to the backing collection is accomplished
2305      * through the returned collection.<p>
2306      *
2307      * It is imperative that the user manually synchronize on the returned
2308      * collection when traversing it via {@link Iterator}, {@link Spliterator}
2309      * or {@link Stream}:
2310      * <pre>
2311      *  Collection c = Collections.synchronizedCollection(myCollection);
2312      *     ...
2313      *  synchronized (c) {
2314      *      Iterator i = c.iterator(); // Must be in the synchronized block
2315      *      while (i.hasNext())
2316      *         foo(i.next());
2317      *  }
2318      * </pre>
2319      * Failure to follow this advice may result in non-deterministic behavior.
2320      *
2321      * <p>The returned collection does <i>not</i> pass the {@code hashCode}
2322      * and {@code equals} operations through to the backing collection, but
2323      * relies on {@code Object}'s equals and hashCode methods.  This is
2324      * necessary to preserve the contracts of these operations in the case
2325      * that the backing collection is a set or a list.<p>
2326      *
2327      * The returned collection will be serializable if the specified collection
2328      * is serializable.
2329      *
2330      * @param  <T> the class of the objects in the collection
2331      * @param  c the collection to be "wrapped" in a synchronized collection.
2332      * @return a synchronized view of the specified collection.
2333      */
2334     public static <T> Collection<T> synchronizedCollection(Collection<T> c) {
2335         return new SynchronizedCollection<>(c);
2336     }
2337 
2338     static <T> Collection<T> synchronizedCollection(Collection<T> c, Object mutex) {
2339         return new SynchronizedCollection<>(c, mutex);
2340     }
2341 
2342     /**
2343      * @serial include
2344      */
2345     static class SynchronizedCollection<E> implements Collection<E>, Serializable {
2346         @java.io.Serial
2347         private static final long serialVersionUID = 3053995032091335093L;
2348 
2349         @SuppressWarnings("serial") // Conditionally serializable
2350         final Collection<E> c;  // Backing Collection
2351         @SuppressWarnings("serial") // Conditionally serializable
2352         final Object mutex;     // Object on which to synchronize
2353 
2354         SynchronizedCollection(Collection<E> c) {
2355             this.c = Objects.requireNonNull(c);
2356             mutex = this;
2357         }
2358 
2359         SynchronizedCollection(Collection<E> c, Object mutex) {
2360             this.c = Objects.requireNonNull(c);
2361             this.mutex = Objects.requireNonNull(mutex);
2362         }
2363 
2364         public int size() {
2365             synchronized (mutex) {return c.size();}
2366         }
2367         public boolean isEmpty() {
2368             synchronized (mutex) {return c.isEmpty();}
2369         }
2370         public boolean contains(Object o) {
2371             synchronized (mutex) {return c.contains(o);}
2372         }
2373         public Object[] toArray() {
2374             synchronized (mutex) {return c.toArray();}
2375         }
2376         public <T> T[] toArray(T[] a) {
2377             synchronized (mutex) {return c.toArray(a);}
2378         }
2379         public <T> T[] toArray(IntFunction<T[]> f) {
2380             synchronized (mutex) {return c.toArray(f);}
2381         }
2382 
2383         public Iterator<E> iterator() {
2384             return c.iterator(); // Must be manually synched by user!
2385         }
2386 
2387         public boolean add(E e) {
2388             synchronized (mutex) {return c.add(e);}
2389         }
2390         public boolean remove(Object o) {
2391             synchronized (mutex) {return c.remove(o);}
2392         }
2393 
2394         public boolean containsAll(Collection<?> coll) {
2395             synchronized (mutex) {return c.containsAll(coll);}
2396         }
2397         public boolean addAll(Collection<? extends E> coll) {
2398             synchronized (mutex) {return c.addAll(coll);}
2399         }
2400         public boolean removeAll(Collection<?> coll) {
2401             synchronized (mutex) {return c.removeAll(coll);}
2402         }
2403         public boolean retainAll(Collection<?> coll) {
2404             synchronized (mutex) {return c.retainAll(coll);}
2405         }
2406         public void clear() {
2407             synchronized (mutex) {c.clear();}
2408         }
2409         public String toString() {
2410             synchronized (mutex) {return c.toString();}
2411         }
2412         // Override default methods in Collection
2413         @Override
2414         public void forEach(Consumer<? super E> consumer) {
2415             synchronized (mutex) {c.forEach(consumer);}
2416         }
2417         @Override
2418         public boolean removeIf(Predicate<? super E> filter) {
2419             synchronized (mutex) {return c.removeIf(filter);}
2420         }
2421         @Override
2422         public Spliterator<E> spliterator() {
2423             return c.spliterator(); // Must be manually synched by user!
2424         }
2425         @Override
2426         public Stream<E> stream() {
2427             return c.stream(); // Must be manually synched by user!
2428         }
2429         @Override
2430         public Stream<E> parallelStream() {
2431             return c.parallelStream(); // Must be manually synched by user!
2432         }
2433         @java.io.Serial
2434         private void writeObject(ObjectOutputStream s) throws IOException {
2435             synchronized (mutex) {s.defaultWriteObject();}
2436         }
2437     }
2438 
2439     /**
2440      * Returns a synchronized (thread-safe) set backed by the specified
2441      * set.  In order to guarantee serial access, it is critical that
2442      * <strong>all</strong> access to the backing set is accomplished
2443      * through the returned set.<p>
2444      *
2445      * It is imperative that the user manually synchronize on the returned
2446      * collection when traversing it via {@link Iterator}, {@link Spliterator}
2447      * or {@link Stream}:
2448      * <pre>
2449      *  Set s = Collections.synchronizedSet(new HashSet());
2450      *      ...
2451      *  synchronized (s) {
2452      *      Iterator i = s.iterator(); // Must be in the synchronized block
2453      *      while (i.hasNext())
2454      *          foo(i.next());
2455      *  }
2456      * </pre>
2457      * Failure to follow this advice may result in non-deterministic behavior.
2458      *
2459      * <p>The returned set will be serializable if the specified set is
2460      * serializable.
2461      *
2462      * @param  <T> the class of the objects in the set
2463      * @param  s the set to be "wrapped" in a synchronized set.
2464      * @return a synchronized view of the specified set.
2465      */
2466     public static <T> Set<T> synchronizedSet(Set<T> s) {
2467         return new SynchronizedSet<>(s);
2468     }
2469 
2470     static <T> Set<T> synchronizedSet(Set<T> s, Object mutex) {
2471         return new SynchronizedSet<>(s, mutex);
2472     }
2473 
2474     /**
2475      * @serial include
2476      */
2477     static class SynchronizedSet<E>
2478           extends SynchronizedCollection<E>
2479           implements Set<E> {
2480         @java.io.Serial
2481         private static final long serialVersionUID = 487447009682186044L;
2482 
2483         SynchronizedSet(Set<E> s) {
2484             super(s);
2485         }
2486         SynchronizedSet(Set<E> s, Object mutex) {
2487             super(s, mutex);
2488         }
2489 
2490         public boolean equals(Object o) {
2491             if (this == o)
2492                 return true;
2493             synchronized (mutex) {return c.equals(o);}
2494         }
2495         public int hashCode() {
2496             synchronized (mutex) {return c.hashCode();}
2497         }
2498     }
2499 
2500     /**
2501      * Returns a synchronized (thread-safe) sorted set backed by the specified
2502      * sorted set.  In order to guarantee serial access, it is critical that
2503      * <strong>all</strong> access to the backing sorted set is accomplished
2504      * through the returned sorted set (or its views).<p>
2505      *
2506      * It is imperative that the user manually synchronize on the returned
2507      * sorted set when traversing it or any of its {@code subSet},
2508      * {@code headSet}, or {@code tailSet} views via {@link Iterator},
2509      * {@link Spliterator} or {@link Stream}:
2510      * <pre>
2511      *  SortedSet s = Collections.synchronizedSortedSet(new TreeSet());
2512      *      ...
2513      *  synchronized (s) {
2514      *      Iterator i = s.iterator(); // Must be in the synchronized block
2515      *      while (i.hasNext())
2516      *          foo(i.next());
2517      *  }
2518      * </pre>
2519      * or:
2520      * <pre>
2521      *  SortedSet s = Collections.synchronizedSortedSet(new TreeSet());
2522      *  SortedSet s2 = s.headSet(foo);
2523      *      ...
2524      *  synchronized (s) {  // Note: s, not s2!!!
2525      *      Iterator i = s2.iterator(); // Must be in the synchronized block
2526      *      while (i.hasNext())
2527      *          foo(i.next());
2528      *  }
2529      * </pre>
2530      * Failure to follow this advice may result in non-deterministic behavior.
2531      *
2532      * <p>The returned sorted set will be serializable if the specified
2533      * sorted set is serializable.
2534      *
2535      * @param  <T> the class of the objects in the set
2536      * @param  s the sorted set to be "wrapped" in a synchronized sorted set.
2537      * @return a synchronized view of the specified sorted set.
2538      */
2539     public static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s) {
2540         return new SynchronizedSortedSet<>(s);
2541     }
2542 
2543     /**
2544      * @serial include
2545      */
2546     static class SynchronizedSortedSet<E>
2547         extends SynchronizedSet<E>
2548         implements SortedSet<E>
2549     {
2550         @java.io.Serial
2551         private static final long serialVersionUID = 8695801310862127406L;
2552 
2553         @SuppressWarnings("serial") // Conditionally serializable
2554         private final SortedSet<E> ss;
2555 
2556         SynchronizedSortedSet(SortedSet<E> s) {
2557             super(s);
2558             ss = s;
2559         }
2560         SynchronizedSortedSet(SortedSet<E> s, Object mutex) {
2561             super(s, mutex);
2562             ss = s;
2563         }
2564 
2565         public Comparator<? super E> comparator() {
2566             synchronized (mutex) {return ss.comparator();}
2567         }
2568 
2569         public SortedSet<E> subSet(E fromElement, E toElement) {
2570             synchronized (mutex) {
2571                 return new SynchronizedSortedSet<>(
2572                     ss.subSet(fromElement, toElement), mutex);
2573             }
2574         }
2575         public SortedSet<E> headSet(E toElement) {
2576             synchronized (mutex) {
2577                 return new SynchronizedSortedSet<>(ss.headSet(toElement), mutex);
2578             }
2579         }
2580         public SortedSet<E> tailSet(E fromElement) {
2581             synchronized (mutex) {
2582                return new SynchronizedSortedSet<>(ss.tailSet(fromElement),mutex);
2583             }
2584         }
2585 
2586         public E first() {
2587             synchronized (mutex) {return ss.first();}
2588         }
2589         public E last() {
2590             synchronized (mutex) {return ss.last();}
2591         }
2592     }
2593 
2594     /**
2595      * Returns a synchronized (thread-safe) navigable set backed by the
2596      * specified navigable set.  In order to guarantee serial access, it is
2597      * critical that <strong>all</strong> access to the backing navigable set is
2598      * accomplished through the returned navigable set (or its views).<p>
2599      *
2600      * It is imperative that the user manually synchronize on the returned
2601      * navigable set when traversing it, or any of its {@code subSet},
2602      * {@code headSet}, or {@code tailSet} views, via {@link Iterator},
2603      * {@link Spliterator} or {@link Stream}:
2604      * <pre>
2605      *  NavigableSet s = Collections.synchronizedNavigableSet(new TreeSet());
2606      *      ...
2607      *  synchronized (s) {
2608      *      Iterator i = s.iterator(); // Must be in the synchronized block
2609      *      while (i.hasNext())
2610      *          foo(i.next());
2611      *  }
2612      * </pre>
2613      * or:
2614      * <pre>
2615      *  NavigableSet s = Collections.synchronizedNavigableSet(new TreeSet());
2616      *  NavigableSet s2 = s.headSet(foo, true);
2617      *      ...
2618      *  synchronized (s) {  // Note: s, not s2!!!
2619      *      Iterator i = s2.iterator(); // Must be in the synchronized block
2620      *      while (i.hasNext())
2621      *          foo(i.next());
2622      *  }
2623      * </pre>
2624      * Failure to follow this advice may result in non-deterministic behavior.
2625      *
2626      * <p>The returned navigable set will be serializable if the specified
2627      * navigable set is serializable.
2628      *
2629      * @param  <T> the class of the objects in the set
2630      * @param  s the navigable set to be "wrapped" in a synchronized navigable
2631      * set
2632      * @return a synchronized view of the specified navigable set
2633      * @since 1.8
2634      */
2635     public static <T> NavigableSet<T> synchronizedNavigableSet(NavigableSet<T> s) {
2636         return new SynchronizedNavigableSet<>(s);
2637     }
2638 
2639     /**
2640      * @serial include
2641      */
2642     static class SynchronizedNavigableSet<E>
2643         extends SynchronizedSortedSet<E>
2644         implements NavigableSet<E>
2645     {
2646         @java.io.Serial
2647         private static final long serialVersionUID = -5505529816273629798L;
2648 
2649         @SuppressWarnings("serial") // Conditionally serializable
2650         private final NavigableSet<E> ns;
2651 
2652         SynchronizedNavigableSet(NavigableSet<E> s) {
2653             super(s);
2654             ns = s;
2655         }
2656 
2657         SynchronizedNavigableSet(NavigableSet<E> s, Object mutex) {
2658             super(s, mutex);
2659             ns = s;
2660         }
2661         public E lower(E e)      { synchronized (mutex) {return ns.lower(e);} }
2662         public E floor(E e)      { synchronized (mutex) {return ns.floor(e);} }
2663         public E ceiling(E e)  { synchronized (mutex) {return ns.ceiling(e);} }
2664         public E higher(E e)    { synchronized (mutex) {return ns.higher(e);} }
2665         public E pollFirst()  { synchronized (mutex) {return ns.pollFirst();} }
2666         public E pollLast()    { synchronized (mutex) {return ns.pollLast();} }
2667 
2668         public NavigableSet<E> descendingSet() {
2669             synchronized (mutex) {
2670                 return new SynchronizedNavigableSet<>(ns.descendingSet(), mutex);
2671             }
2672         }
2673 
2674         public Iterator<E> descendingIterator()
2675                  { synchronized (mutex) { return descendingSet().iterator(); } }
2676 
2677         public NavigableSet<E> subSet(E fromElement, E toElement) {
2678             synchronized (mutex) {
2679                 return new SynchronizedNavigableSet<>(ns.subSet(fromElement, true, toElement, false), mutex);
2680             }
2681         }
2682         public NavigableSet<E> headSet(E toElement) {
2683             synchronized (mutex) {
2684                 return new SynchronizedNavigableSet<>(ns.headSet(toElement, false), mutex);
2685             }
2686         }
2687         public NavigableSet<E> tailSet(E fromElement) {
2688             synchronized (mutex) {
2689                 return new SynchronizedNavigableSet<>(ns.tailSet(fromElement, true), mutex);
2690             }
2691         }
2692 
2693         public NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
2694             synchronized (mutex) {
2695                 return new SynchronizedNavigableSet<>(ns.subSet(fromElement, fromInclusive, toElement, toInclusive), mutex);
2696             }
2697         }
2698 
2699         public NavigableSet<E> headSet(E toElement, boolean inclusive) {
2700             synchronized (mutex) {
2701                 return new SynchronizedNavigableSet<>(ns.headSet(toElement, inclusive), mutex);
2702             }
2703         }
2704 
2705         public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
2706             synchronized (mutex) {
2707                 return new SynchronizedNavigableSet<>(ns.tailSet(fromElement, inclusive), mutex);
2708             }
2709         }
2710     }
2711 
2712     /**
2713      * Returns a synchronized (thread-safe) list backed by the specified
2714      * list.  In order to guarantee serial access, it is critical that
2715      * <strong>all</strong> access to the backing list is accomplished
2716      * through the returned list.<p>
2717      *
2718      * It is imperative that the user manually synchronize on the returned
2719      * list when traversing it via {@link Iterator}, {@link Spliterator}
2720      * or {@link Stream}:
2721      * <pre>
2722      *  List list = Collections.synchronizedList(new ArrayList());
2723      *      ...
2724      *  synchronized (list) {
2725      *      Iterator i = list.iterator(); // Must be in synchronized block
2726      *      while (i.hasNext())
2727      *          foo(i.next());
2728      *  }
2729      * </pre>
2730      * Failure to follow this advice may result in non-deterministic behavior.
2731      *
2732      * <p>The returned list will be serializable if the specified list is
2733      * serializable.
2734      *
2735      * @param  <T> the class of the objects in the list
2736      * @param  list the list to be "wrapped" in a synchronized list.
2737      * @return a synchronized view of the specified list.
2738      */
2739     public static <T> List<T> synchronizedList(List<T> list) {
2740         return (list instanceof RandomAccess ?
2741                 new SynchronizedRandomAccessList<>(list) :
2742                 new SynchronizedList<>(list));
2743     }
2744 
2745     static <T> List<T> synchronizedList(List<T> list, Object mutex) {
2746         return (list instanceof RandomAccess ?
2747                 new SynchronizedRandomAccessList<>(list, mutex) :
2748                 new SynchronizedList<>(list, mutex));
2749     }
2750 
2751     /**
2752      * @serial include
2753      */
2754     static class SynchronizedList<E>
2755         extends SynchronizedCollection<E>
2756         implements List<E> {
2757         @java.io.Serial
2758         private static final long serialVersionUID = -7754090372962971524L;
2759 
2760         @SuppressWarnings("serial") // Conditionally serializable
2761         final List<E> list;
2762 
2763         SynchronizedList(List<E> list) {
2764             super(list);
2765             this.list = list;
2766         }
2767         SynchronizedList(List<E> list, Object mutex) {
2768             super(list, mutex);
2769             this.list = list;
2770         }
2771 
2772         public boolean equals(Object o) {
2773             if (this == o)
2774                 return true;
2775             synchronized (mutex) {return list.equals(o);}
2776         }
2777         public int hashCode() {
2778             synchronized (mutex) {return list.hashCode();}
2779         }
2780 
2781         public E get(int index) {
2782             synchronized (mutex) {return list.get(index);}
2783         }
2784         public E set(int index, E element) {
2785             synchronized (mutex) {return list.set(index, element);}
2786         }
2787         public void add(int index, E element) {
2788             synchronized (mutex) {list.add(index, element);}
2789         }
2790         public E remove(int index) {
2791             synchronized (mutex) {return list.remove(index);}
2792         }
2793 
2794         public int indexOf(Object o) {
2795             synchronized (mutex) {return list.indexOf(o);}
2796         }
2797         public int lastIndexOf(Object o) {
2798             synchronized (mutex) {return list.lastIndexOf(o);}
2799         }
2800 
2801         public boolean addAll(int index, Collection<? extends E> c) {
2802             synchronized (mutex) {return list.addAll(index, c);}
2803         }
2804 
2805         public ListIterator<E> listIterator() {
2806             return list.listIterator(); // Must be manually synched by user
2807         }
2808 
2809         public ListIterator<E> listIterator(int index) {
2810             return list.listIterator(index); // Must be manually synched by user
2811         }
2812 
2813         public List<E> subList(int fromIndex, int toIndex) {
2814             synchronized (mutex) {
2815                 return new SynchronizedList<>(list.subList(fromIndex, toIndex),
2816                                             mutex);
2817             }
2818         }
2819 
2820         @Override
2821         public void replaceAll(UnaryOperator<E> operator) {
2822             synchronized (mutex) {list.replaceAll(operator);}
2823         }
2824         @Override
2825         public void sort(Comparator<? super E> c) {
2826             synchronized (mutex) {list.sort(c);}
2827         }
2828 
2829         /**
2830          * SynchronizedRandomAccessList instances are serialized as
2831          * SynchronizedList instances to allow them to be deserialized
2832          * in pre-1.4 JREs (which do not have SynchronizedRandomAccessList).
2833          * This method inverts the transformation.  As a beneficial
2834          * side-effect, it also grafts the RandomAccess marker onto
2835          * SynchronizedList instances that were serialized in pre-1.4 JREs.
2836          *
2837          * Note: Unfortunately, SynchronizedRandomAccessList instances
2838          * serialized in 1.4.1 and deserialized in 1.4 will become
2839          * SynchronizedList instances, as this method was missing in 1.4.
2840          */
2841         @java.io.Serial
2842         private Object readResolve() {
2843             return (list instanceof RandomAccess
2844                     ? new SynchronizedRandomAccessList<>(list)
2845                     : this);
2846         }
2847     }
2848 
2849     /**
2850      * @serial include
2851      */
2852     static class SynchronizedRandomAccessList<E>
2853         extends SynchronizedList<E>
2854         implements RandomAccess {
2855 
2856         SynchronizedRandomAccessList(List<E> list) {
2857             super(list);
2858         }
2859 
2860         SynchronizedRandomAccessList(List<E> list, Object mutex) {
2861             super(list, mutex);
2862         }
2863 
2864         public List<E> subList(int fromIndex, int toIndex) {
2865             synchronized (mutex) {
2866                 return new SynchronizedRandomAccessList<>(
2867                     list.subList(fromIndex, toIndex), mutex);
2868             }
2869         }
2870 
2871         @java.io.Serial
2872         private static final long serialVersionUID = 1530674583602358482L;
2873 
2874         /**
2875          * Allows instances to be deserialized in pre-1.4 JREs (which do
2876          * not have SynchronizedRandomAccessList).  SynchronizedList has
2877          * a readResolve method that inverts this transformation upon
2878          * deserialization.
2879          */
2880         @java.io.Serial
2881         private Object writeReplace() {
2882             return new SynchronizedList<>(list);
2883         }
2884     }
2885 
2886     /**
2887      * Returns a synchronized (thread-safe) map backed by the specified
2888      * map.  In order to guarantee serial access, it is critical that
2889      * <strong>all</strong> access to the backing map is accomplished
2890      * through the returned map.<p>
2891      *
2892      * It is imperative that the user manually synchronize on the returned
2893      * map when traversing any of its collection views via {@link Iterator},
2894      * {@link Spliterator} or {@link Stream}:
2895      * <pre>
2896      *  Map m = Collections.synchronizedMap(new HashMap());
2897      *      ...
2898      *  Set s = m.keySet();  // Needn't be in synchronized block
2899      *      ...
2900      *  synchronized (m) {  // Synchronizing on m, not s!
2901      *      Iterator i = s.iterator(); // Must be in synchronized block
2902      *      while (i.hasNext())
2903      *          foo(i.next());
2904      *  }
2905      * </pre>
2906      * Failure to follow this advice may result in non-deterministic behavior.
2907      *
2908      * <p>The returned map will be serializable if the specified map is
2909      * serializable.
2910      *
2911      * @param <K> the class of the map keys
2912      * @param <V> the class of the map values
2913      * @param  m the map to be "wrapped" in a synchronized map.
2914      * @return a synchronized view of the specified map.
2915      */
2916     public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
2917         return new SynchronizedMap<>(m);
2918     }
2919 
2920     /**
2921      * @serial include
2922      */
2923     private static class SynchronizedMap<K,V>
2924         implements Map<K,V>, Serializable {
2925         @java.io.Serial
2926         private static final long serialVersionUID = 1978198479659022715L;
2927 
2928         @SuppressWarnings("serial") // Conditionally serializable
2929         private final Map<K,V> m;     // Backing Map
2930         @SuppressWarnings("serial") // Conditionally serializable
2931         final Object      mutex;        // Object on which to synchronize
2932 
2933         SynchronizedMap(Map<K,V> m) {
2934             this.m = Objects.requireNonNull(m);
2935             mutex = this;
2936         }
2937 
2938         SynchronizedMap(Map<K,V> m, Object mutex) {
2939             this.m = m;
2940             this.mutex = mutex;
2941         }
2942 
2943         public int size() {
2944             synchronized (mutex) {return m.size();}
2945         }
2946         public boolean isEmpty() {
2947             synchronized (mutex) {return m.isEmpty();}
2948         }
2949         public boolean containsKey(Object key) {
2950             synchronized (mutex) {return m.containsKey(key);}
2951         }
2952         public boolean containsValue(Object value) {
2953             synchronized (mutex) {return m.containsValue(value);}
2954         }
2955         public V get(Object key) {
2956             synchronized (mutex) {return m.get(key);}
2957         }
2958 
2959         public V put(K key, V value) {
2960             synchronized (mutex) {return m.put(key, value);}
2961         }
2962         public V remove(Object key) {
2963             synchronized (mutex) {return m.remove(key);}
2964         }
2965         public void putAll(Map<? extends K, ? extends V> map) {
2966             synchronized (mutex) {m.putAll(map);}
2967         }
2968         public void clear() {
2969             synchronized (mutex) {m.clear();}
2970         }
2971 
2972         private transient Set<K> keySet;
2973         private transient Set<Map.Entry<K,V>> entrySet;
2974         private transient Collection<V> values;
2975 
2976         public Set<K> keySet() {
2977             synchronized (mutex) {
2978                 if (keySet==null)
2979                     keySet = new SynchronizedSet<>(m.keySet(), mutex);
2980                 return keySet;
2981             }
2982         }
2983 
2984         public Set<Map.Entry<K,V>> entrySet() {
2985             synchronized (mutex) {
2986                 if (entrySet==null)
2987                     entrySet = new SynchronizedSet<>(m.entrySet(), mutex);
2988                 return entrySet;
2989             }
2990         }
2991 
2992         public Collection<V> values() {
2993             synchronized (mutex) {
2994                 if (values==null)
2995                     values = new SynchronizedCollection<>(m.values(), mutex);
2996                 return values;
2997             }
2998         }
2999 
3000         public boolean equals(Object o) {
3001             if (this == o)
3002                 return true;
3003             synchronized (mutex) {return m.equals(o);}
3004         }
3005         public int hashCode() {
3006             synchronized (mutex) {return m.hashCode();}
3007         }
3008         public String toString() {
3009             synchronized (mutex) {return m.toString();}
3010         }
3011 
3012         // Override default methods in Map
3013         @Override
3014         public V getOrDefault(Object k, V defaultValue) {
3015             synchronized (mutex) {return m.getOrDefault(k, defaultValue);}
3016         }
3017         @Override
3018         public void forEach(BiConsumer<? super K, ? super V> action) {
3019             synchronized (mutex) {m.forEach(action);}
3020         }
3021         @Override
3022         public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
3023             synchronized (mutex) {m.replaceAll(function);}
3024         }
3025         @Override
3026         public V putIfAbsent(K key, V value) {
3027             synchronized (mutex) {return m.putIfAbsent(key, value);}
3028         }
3029         @Override
3030         public boolean remove(Object key, Object value) {
3031             synchronized (mutex) {return m.remove(key, value);}
3032         }
3033         @Override
3034         public boolean replace(K key, V oldValue, V newValue) {
3035             synchronized (mutex) {return m.replace(key, oldValue, newValue);}
3036         }
3037         @Override
3038         public V replace(K key, V value) {
3039             synchronized (mutex) {return m.replace(key, value);}
3040         }
3041         @Override
3042         public V computeIfAbsent(K key,
3043                 Function<? super K, ? extends V> mappingFunction) {
3044             synchronized (mutex) {return m.computeIfAbsent(key, mappingFunction);}
3045         }
3046         @Override
3047         public V computeIfPresent(K key,
3048                 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
3049             synchronized (mutex) {return m.computeIfPresent(key, remappingFunction);}
3050         }
3051         @Override
3052         public V compute(K key,
3053                 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
3054             synchronized (mutex) {return m.compute(key, remappingFunction);}
3055         }
3056         @Override
3057         public V merge(K key, V value,
3058                 BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
3059             synchronized (mutex) {return m.merge(key, value, remappingFunction);}
3060         }
3061 
3062         @java.io.Serial
3063         private void writeObject(ObjectOutputStream s) throws IOException {
3064             synchronized (mutex) {s.defaultWriteObject();}
3065         }
3066     }
3067 
3068     /**
3069      * Returns a synchronized (thread-safe) sorted map backed by the specified
3070      * sorted map.  In order to guarantee serial access, it is critical that
3071      * <strong>all</strong> access to the backing sorted map is accomplished
3072      * through the returned sorted map (or its views).<p>
3073      *
3074      * It is imperative that the user manually synchronize on the returned
3075      * sorted map when traversing any of its collection views, or the
3076      * collections views of any of its {@code subMap}, {@code headMap} or
3077      * {@code tailMap} views, via {@link Iterator}, {@link Spliterator} or
3078      * {@link Stream}:
3079      * <pre>
3080      *  SortedMap m = Collections.synchronizedSortedMap(new TreeMap());
3081      *      ...
3082      *  Set s = m.keySet();  // Needn't be in synchronized block
3083      *      ...
3084      *  synchronized (m) {  // Synchronizing on m, not s!
3085      *      Iterator i = s.iterator(); // Must be in synchronized block
3086      *      while (i.hasNext())
3087      *          foo(i.next());
3088      *  }
3089      * </pre>
3090      * or:
3091      * <pre>
3092      *  SortedMap m = Collections.synchronizedSortedMap(new TreeMap());
3093      *  SortedMap m2 = m.subMap(foo, bar);
3094      *      ...
3095      *  Set s2 = m2.keySet();  // Needn't be in synchronized block
3096      *      ...
3097      *  synchronized (m) {  // Synchronizing on m, not m2 or s2!
3098      *      Iterator i = s2.iterator(); // Must be in synchronized block
3099      *      while (i.hasNext())
3100      *          foo(i.next());
3101      *  }
3102      * </pre>
3103      * Failure to follow this advice may result in non-deterministic behavior.
3104      *
3105      * <p>The returned sorted map will be serializable if the specified
3106      * sorted map is serializable.
3107      *
3108      * @param <K> the class of the map keys
3109      * @param <V> the class of the map values
3110      * @param  m the sorted map to be "wrapped" in a synchronized sorted map.
3111      * @return a synchronized view of the specified sorted map.
3112      */
3113     public static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m) {
3114         return new SynchronizedSortedMap<>(m);
3115     }
3116 
3117     /**
3118      * @serial include
3119      */
3120     static class SynchronizedSortedMap<K,V>
3121         extends SynchronizedMap<K,V>
3122         implements SortedMap<K,V>
3123     {
3124         @java.io.Serial
3125         private static final long serialVersionUID = -8798146769416483793L;
3126 
3127         @SuppressWarnings("serial") // Conditionally serializable
3128         private final SortedMap<K,V> sm;
3129 
3130         SynchronizedSortedMap(SortedMap<K,V> m) {
3131             super(m);
3132             sm = m;
3133         }
3134         SynchronizedSortedMap(SortedMap<K,V> m, Object mutex) {
3135             super(m, mutex);
3136             sm = m;
3137         }
3138 
3139         public Comparator<? super K> comparator() {
3140             synchronized (mutex) {return sm.comparator();}
3141         }
3142 
3143         public SortedMap<K,V> subMap(K fromKey, K toKey) {
3144             synchronized (mutex) {
3145                 return new SynchronizedSortedMap<>(
3146                     sm.subMap(fromKey, toKey), mutex);
3147             }
3148         }
3149         public SortedMap<K,V> headMap(K toKey) {
3150             synchronized (mutex) {
3151                 return new SynchronizedSortedMap<>(sm.headMap(toKey), mutex);
3152             }
3153         }
3154         public SortedMap<K,V> tailMap(K fromKey) {
3155             synchronized (mutex) {
3156                return new SynchronizedSortedMap<>(sm.tailMap(fromKey),mutex);
3157             }
3158         }
3159 
3160         public K firstKey() {
3161             synchronized (mutex) {return sm.firstKey();}
3162         }
3163         public K lastKey() {
3164             synchronized (mutex) {return sm.lastKey();}
3165         }
3166     }
3167 
3168     /**
3169      * Returns a synchronized (thread-safe) navigable map backed by the
3170      * specified navigable map.  In order to guarantee serial access, it is
3171      * critical that <strong>all</strong> access to the backing navigable map is
3172      * accomplished through the returned navigable map (or its views).<p>
3173      *
3174      * It is imperative that the user manually synchronize on the returned
3175      * navigable map when traversing any of its collection views, or the
3176      * collections views of any of its {@code subMap}, {@code headMap} or
3177      * {@code tailMap} views, via {@link Iterator}, {@link Spliterator} or
3178      * {@link Stream}:
3179      * <pre>
3180      *  NavigableMap m = Collections.synchronizedNavigableMap(new TreeMap());
3181      *      ...
3182      *  Set s = m.keySet();  // Needn't be in synchronized block
3183      *      ...
3184      *  synchronized (m) {  // Synchronizing on m, not s!
3185      *      Iterator i = s.iterator(); // Must be in synchronized block
3186      *      while (i.hasNext())
3187      *          foo(i.next());
3188      *  }
3189      * </pre>
3190      * or:
3191      * <pre>
3192      *  NavigableMap m = Collections.synchronizedNavigableMap(new TreeMap());
3193      *  NavigableMap m2 = m.subMap(foo, true, bar, false);
3194      *      ...
3195      *  Set s2 = m2.keySet();  // Needn't be in synchronized block
3196      *      ...
3197      *  synchronized (m) {  // Synchronizing on m, not m2 or s2!
3198      *      Iterator i = s2.iterator(); // Must be in synchronized block
3199      *      while (i.hasNext())
3200      *          foo(i.next());
3201      *  }
3202      * </pre>
3203      * Failure to follow this advice may result in non-deterministic behavior.
3204      *
3205      * <p>The returned navigable map will be serializable if the specified
3206      * navigable map is serializable.
3207      *
3208      * @param <K> the class of the map keys
3209      * @param <V> the class of the map values
3210      * @param  m the navigable map to be "wrapped" in a synchronized navigable
3211      *              map
3212      * @return a synchronized view of the specified navigable map.
3213      * @since 1.8
3214      */
3215     public static <K,V> NavigableMap<K,V> synchronizedNavigableMap(NavigableMap<K,V> m) {
3216         return new SynchronizedNavigableMap<>(m);
3217     }
3218 
3219     /**
3220      * A synchronized NavigableMap.
3221      *
3222      * @serial include
3223      */
3224     static class SynchronizedNavigableMap<K,V>
3225         extends SynchronizedSortedMap<K,V>
3226         implements NavigableMap<K,V>
3227     {
3228         @java.io.Serial
3229         private static final long serialVersionUID = 699392247599746807L;
3230 
3231         @SuppressWarnings("serial") // Conditionally serializable
3232         private final NavigableMap<K,V> nm;
3233 
3234         SynchronizedNavigableMap(NavigableMap<K,V> m) {
3235             super(m);
3236             nm = m;
3237         }
3238         SynchronizedNavigableMap(NavigableMap<K,V> m, Object mutex) {
3239             super(m, mutex);
3240             nm = m;
3241         }
3242 
3243         public Entry<K, V> lowerEntry(K key)
3244                         { synchronized (mutex) { return nm.lowerEntry(key); } }
3245         public K lowerKey(K key)
3246                           { synchronized (mutex) { return nm.lowerKey(key); } }
3247         public Entry<K, V> floorEntry(K key)
3248                         { synchronized (mutex) { return nm.floorEntry(key); } }
3249         public K floorKey(K key)
3250                           { synchronized (mutex) { return nm.floorKey(key); } }
3251         public Entry<K, V> ceilingEntry(K key)
3252                       { synchronized (mutex) { return nm.ceilingEntry(key); } }
3253         public K ceilingKey(K key)
3254                         { synchronized (mutex) { return nm.ceilingKey(key); } }
3255         public Entry<K, V> higherEntry(K key)
3256                        { synchronized (mutex) { return nm.higherEntry(key); } }
3257         public K higherKey(K key)
3258                          { synchronized (mutex) { return nm.higherKey(key); } }
3259         public Entry<K, V> firstEntry()
3260                            { synchronized (mutex) { return nm.firstEntry(); } }
3261         public Entry<K, V> lastEntry()
3262                             { synchronized (mutex) { return nm.lastEntry(); } }
3263         public Entry<K, V> pollFirstEntry()
3264                        { synchronized (mutex) { return nm.pollFirstEntry(); } }
3265         public Entry<K, V> pollLastEntry()
3266                         { synchronized (mutex) { return nm.pollLastEntry(); } }
3267 
3268         public NavigableMap<K, V> descendingMap() {
3269             synchronized (mutex) {
3270                 return
3271                     new SynchronizedNavigableMap<>(nm.descendingMap(), mutex);
3272             }
3273         }
3274 
3275         public NavigableSet<K> keySet() {
3276             return navigableKeySet();
3277         }
3278 
3279         public NavigableSet<K> navigableKeySet() {
3280             synchronized (mutex) {
3281                 return new SynchronizedNavigableSet<>(nm.navigableKeySet(), mutex);
3282             }
3283         }
3284 
3285         public NavigableSet<K> descendingKeySet() {
3286             synchronized (mutex) {
3287                 return new SynchronizedNavigableSet<>(nm.descendingKeySet(), mutex);
3288             }
3289         }
3290 
3291 
3292         public SortedMap<K,V> subMap(K fromKey, K toKey) {
3293             synchronized (mutex) {
3294                 return new SynchronizedNavigableMap<>(
3295                     nm.subMap(fromKey, true, toKey, false), mutex);
3296             }
3297         }
3298         public SortedMap<K,V> headMap(K toKey) {
3299             synchronized (mutex) {
3300                 return new SynchronizedNavigableMap<>(nm.headMap(toKey, false), mutex);
3301             }
3302         }
3303         public SortedMap<K,V> tailMap(K fromKey) {
3304             synchronized (mutex) {
3305         return new SynchronizedNavigableMap<>(nm.tailMap(fromKey, true),mutex);
3306             }
3307         }
3308 
3309         public NavigableMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
3310             synchronized (mutex) {
3311                 return new SynchronizedNavigableMap<>(
3312                     nm.subMap(fromKey, fromInclusive, toKey, toInclusive), mutex);
3313             }
3314         }
3315 
3316         public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
3317             synchronized (mutex) {
3318                 return new SynchronizedNavigableMap<>(
3319                         nm.headMap(toKey, inclusive), mutex);
3320             }
3321         }
3322 
3323         public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
3324             synchronized (mutex) {
3325                 return new SynchronizedNavigableMap<>(
3326                     nm.tailMap(fromKey, inclusive), mutex);
3327             }
3328         }
3329     }
3330 
3331     // Dynamically typesafe collection wrappers
3332 
3333     /**
3334      * Returns a dynamically typesafe view of the specified collection.
3335      * Any attempt to insert an element of the wrong type will result in an
3336      * immediate {@link ClassCastException}.  Assuming a collection
3337      * contains no incorrectly typed elements prior to the time a
3338      * dynamically typesafe view is generated, and that all subsequent
3339      * access to the collection takes place through the view, it is
3340      * <i>guaranteed</i> that the collection cannot contain an incorrectly
3341      * typed element.
3342      *
3343      * <p>The generics mechanism in the language provides compile-time
3344      * (static) type checking, but it is possible to defeat this mechanism
3345      * with unchecked casts.  Usually this is not a problem, as the compiler
3346      * issues warnings on all such unchecked operations.  There are, however,
3347      * times when static type checking alone is not sufficient.  For example,
3348      * suppose a collection is passed to a third-party library and it is
3349      * imperative that the library code not corrupt the collection by
3350      * inserting an element of the wrong type.
3351      *
3352      * <p>Another use of dynamically typesafe views is debugging.  Suppose a
3353      * program fails with a {@code ClassCastException}, indicating that an
3354      * incorrectly typed element was put into a parameterized collection.
3355      * Unfortunately, the exception can occur at any time after the erroneous
3356      * element is inserted, so it typically provides little or no information
3357      * as to the real source of the problem.  If the problem is reproducible,
3358      * one can quickly determine its source by temporarily modifying the
3359      * program to wrap the collection with a dynamically typesafe view.
3360      * For example, this declaration:
3361      *  <pre> {@code
3362      *     Collection<String> c = new HashSet<>();
3363      * }</pre>
3364      * may be replaced temporarily by this one:
3365      *  <pre> {@code
3366      *     Collection<String> c = Collections.checkedCollection(
3367      *         new HashSet<>(), String.class);
3368      * }</pre>
3369      * Running the program again will cause it to fail at the point where
3370      * an incorrectly typed element is inserted into the collection, clearly
3371      * identifying the source of the problem.  Once the problem is fixed, the
3372      * modified declaration may be reverted back to the original.
3373      *
3374      * <p>The returned collection does <i>not</i> pass the hashCode and equals
3375      * operations through to the backing collection, but relies on
3376      * {@code Object}'s {@code equals} and {@code hashCode} methods.  This
3377      * is necessary to preserve the contracts of these operations in the case
3378      * that the backing collection is a set or a list.
3379      *
3380      * <p>The returned collection will be serializable if the specified
3381      * collection is serializable.
3382      *
3383      * <p>Since {@code null} is considered to be a value of any reference
3384      * type, the returned collection permits insertion of null elements
3385      * whenever the backing collection does.
3386      *
3387      * @param <E> the class of the objects in the collection
3388      * @param c the collection for which a dynamically typesafe view is to be
3389      *          returned
3390      * @param type the type of element that {@code c} is permitted to hold
3391      * @return a dynamically typesafe view of the specified collection
3392      * @since 1.5
3393      */
3394     public static <E> Collection<E> checkedCollection(Collection<E> c,
3395                                                       Class<E> type) {
3396         return new CheckedCollection<>(c, type);
3397     }
3398 
3399     @SuppressWarnings("unchecked")
3400     static <T> T[] zeroLengthArray(Class<T> type) {
3401         return (T[]) Array.newInstance(type, 0);
3402     }
3403 
3404     /**
3405      * @serial include
3406      */
3407     static class CheckedCollection<E> implements Collection<E>, Serializable {
3408         @java.io.Serial
3409         private static final long serialVersionUID = 1578914078182001775L;
3410 
3411         @SuppressWarnings("serial") // Conditionally serializable
3412         final Collection<E> c;
3413         @SuppressWarnings("serial") // Conditionally serializable
3414         final Class<E> type;
3415 
3416         @SuppressWarnings("unchecked")
3417         E typeCheck(Object o) {
3418             if (o != null && !type.isInstance(o))
3419                 throw new ClassCastException(badElementMsg(o));
3420             return (E) o;
3421         }
3422 
3423         private String badElementMsg(Object o) {
3424             return "Attempt to insert " + o.getClass() +
3425                 " element into collection with element type " + type;
3426         }
3427 
3428         CheckedCollection(Collection<E> c, Class<E> type) {
3429             this.c = Objects.requireNonNull(c, "c");
3430             this.type = Objects.requireNonNull(type, "type");
3431         }
3432 
3433         public int size()                          { return c.size(); }
3434         public boolean isEmpty()                   { return c.isEmpty(); }
3435         public boolean contains(Object o)          { return c.contains(o); }
3436         public Object[] toArray()                  { return c.toArray(); }
3437         public <T> T[] toArray(T[] a)              { return c.toArray(a); }
3438         public <T> T[] toArray(IntFunction<T[]> f) { return c.toArray(f); }
3439         public String toString()                   { return c.toString(); }
3440         public boolean remove(Object o)            { return c.remove(o); }
3441         public void clear()                        {        c.clear(); }
3442 
3443         public boolean containsAll(Collection<?> coll) {
3444             return c.containsAll(coll);
3445         }
3446         public boolean removeAll(Collection<?> coll) {
3447             return c.removeAll(coll);
3448         }
3449         public boolean retainAll(Collection<?> coll) {
3450             return c.retainAll(coll);
3451         }
3452 
3453         public Iterator<E> iterator() {
3454             // JDK-6363904 - unwrapped iterator could be typecast to
3455             // ListIterator with unsafe set()
3456             final Iterator<E> it = c.iterator();
3457             return new Iterator<>() {
3458                 public boolean hasNext() { return it.hasNext(); }
3459                 public E next()          { return it.next(); }
3460                 public void remove()     {        it.remove(); }
3461                 public void forEachRemaining(Consumer<? super E> action) {
3462                     it.forEachRemaining(action);
3463                 }
3464             };
3465         }
3466 
3467         public boolean add(E e)          { return c.add(typeCheck(e)); }
3468 
3469         @SuppressWarnings("serial") // Conditionally serializable
3470         private E[] zeroLengthElementArray; // Lazily initialized
3471 
3472         private E[] zeroLengthElementArray() {
3473             return zeroLengthElementArray != null ? zeroLengthElementArray :
3474                 (zeroLengthElementArray = zeroLengthArray(type));
3475         }
3476 
3477         @SuppressWarnings("unchecked")
3478         Collection<E> checkedCopyOf(Collection<? extends E> coll) {
3479             Object[] a;
3480             try {
3481                 E[] z = zeroLengthElementArray();
3482                 a = coll.toArray(z);
3483                 // Defend against coll violating the toArray contract
3484                 if (a.getClass() != z.getClass())
3485                     a = Arrays.copyOf(a, a.length, z.getClass());
3486             } catch (ArrayStoreException ignore) {
3487                 // To get better and consistent diagnostics,
3488                 // we call typeCheck explicitly on each element.
3489                 // We call clone() to defend against coll retaining a
3490                 // reference to the returned array and storing a bad
3491                 // element into it after it has been type checked.
3492                 a = coll.toArray().clone();
3493                 for (Object o : a)
3494                     typeCheck(o);
3495             }
3496             // A slight abuse of the type system, but safe here.
3497             return (Collection<E>) Arrays.asList(a);
3498         }
3499 
3500         public boolean addAll(Collection<? extends E> coll) {
3501             // Doing things this way insulates us from concurrent changes
3502             // in the contents of coll and provides all-or-nothing
3503             // semantics (which we wouldn't get if we type-checked each
3504             // element as we added it)
3505             return c.addAll(checkedCopyOf(coll));
3506         }
3507 
3508         // Override default methods in Collection
3509         @Override
3510         public void forEach(Consumer<? super E> action) {c.forEach(action);}
3511         @Override
3512         public boolean removeIf(Predicate<? super E> filter) {
3513             return c.removeIf(filter);
3514         }
3515         @Override
3516         public Spliterator<E> spliterator() {return c.spliterator();}
3517         @Override
3518         public Stream<E> stream()           {return c.stream();}
3519         @Override
3520         public Stream<E> parallelStream()   {return c.parallelStream();}
3521     }
3522 
3523     /**
3524      * Returns a dynamically typesafe view of the specified queue.
3525      * Any attempt to insert an element of the wrong type will result in
3526      * an immediate {@link ClassCastException}.  Assuming a queue contains
3527      * no incorrectly typed elements prior to the time a dynamically typesafe
3528      * view is generated, and that all subsequent access to the queue
3529      * takes place through the view, it is <i>guaranteed</i> that the
3530      * queue cannot contain an incorrectly typed element.
3531      *
3532      * <p>A discussion of the use of dynamically typesafe views may be
3533      * found in the documentation for the {@link #checkedCollection
3534      * checkedCollection} method.
3535      *
3536      * <p>The returned queue will be serializable if the specified queue
3537      * is serializable.
3538      *
3539      * <p>Since {@code null} is considered to be a value of any reference
3540      * type, the returned queue permits insertion of {@code null} elements
3541      * whenever the backing queue does.
3542      *
3543      * @param <E> the class of the objects in the queue
3544      * @param queue the queue for which a dynamically typesafe view is to be
3545      *             returned
3546      * @param type the type of element that {@code queue} is permitted to hold
3547      * @return a dynamically typesafe view of the specified queue
3548      * @since 1.8
3549      */
3550     public static <E> Queue<E> checkedQueue(Queue<E> queue, Class<E> type) {
3551         return new CheckedQueue<>(queue, type);
3552     }
3553 
3554     /**
3555      * @serial include
3556      */
3557     static class CheckedQueue<E>
3558         extends CheckedCollection<E>
3559         implements Queue<E>, Serializable
3560     {
3561         @java.io.Serial
3562         private static final long serialVersionUID = 1433151992604707767L;
3563         @SuppressWarnings("serial") // Conditionally serializable
3564         final Queue<E> queue;
3565 
3566         CheckedQueue(Queue<E> queue, Class<E> elementType) {
3567             super(queue, elementType);
3568             this.queue = queue;
3569         }
3570 
3571         public E element()              {return queue.element();}
3572         public boolean equals(Object o) {return o == this || c.equals(o);}
3573         public int hashCode()           {return c.hashCode();}
3574         public E peek()                 {return queue.peek();}
3575         public E poll()                 {return queue.poll();}
3576         public E remove()               {return queue.remove();}
3577         public boolean offer(E e)       {return queue.offer(typeCheck(e));}
3578     }
3579 
3580     /**
3581      * Returns a dynamically typesafe view of the specified set.
3582      * Any attempt to insert an element of the wrong type will result in
3583      * an immediate {@link ClassCastException}.  Assuming a set contains
3584      * no incorrectly typed elements prior to the time a dynamically typesafe
3585      * view is generated, and that all subsequent access to the set
3586      * takes place through the view, it is <i>guaranteed</i> that the
3587      * set cannot contain an incorrectly typed element.
3588      *
3589      * <p>A discussion of the use of dynamically typesafe views may be
3590      * found in the documentation for the {@link #checkedCollection
3591      * checkedCollection} method.
3592      *
3593      * <p>The returned set will be serializable if the specified set is
3594      * serializable.
3595      *
3596      * <p>Since {@code null} is considered to be a value of any reference
3597      * type, the returned set permits insertion of null elements whenever
3598      * the backing set does.
3599      *
3600      * @param <E> the class of the objects in the set
3601      * @param s the set for which a dynamically typesafe view is to be
3602      *          returned
3603      * @param type the type of element that {@code s} is permitted to hold
3604      * @return a dynamically typesafe view of the specified set
3605      * @since 1.5
3606      */
3607     public static <E> Set<E> checkedSet(Set<E> s, Class<E> type) {
3608         return new CheckedSet<>(s, type);
3609     }
3610 
3611     /**
3612      * @serial include
3613      */
3614     static class CheckedSet<E> extends CheckedCollection<E>
3615                                  implements Set<E>, Serializable
3616     {
3617         @java.io.Serial
3618         private static final long serialVersionUID = 4694047833775013803L;
3619 
3620         CheckedSet(Set<E> s, Class<E> elementType) { super(s, elementType); }
3621 
3622         public boolean equals(Object o) { return o == this || c.equals(o); }
3623         public int hashCode()           { return c.hashCode(); }
3624     }
3625 
3626     /**
3627      * Returns a dynamically typesafe view of the specified sorted set.
3628      * Any attempt to insert an element of the wrong type will result in an
3629      * immediate {@link ClassCastException}.  Assuming a sorted set
3630      * contains no incorrectly typed elements prior to the time a
3631      * dynamically typesafe view is generated, and that all subsequent
3632      * access to the sorted set takes place through the view, it is
3633      * <i>guaranteed</i> that the sorted set cannot contain an incorrectly
3634      * typed element.
3635      *
3636      * <p>A discussion of the use of dynamically typesafe views may be
3637      * found in the documentation for the {@link #checkedCollection
3638      * checkedCollection} method.
3639      *
3640      * <p>The returned sorted set will be serializable if the specified sorted
3641      * set is serializable.
3642      *
3643      * <p>Since {@code null} is considered to be a value of any reference
3644      * type, the returned sorted set permits insertion of null elements
3645      * whenever the backing sorted set does.
3646      *
3647      * @param <E> the class of the objects in the set
3648      * @param s the sorted set for which a dynamically typesafe view is to be
3649      *          returned
3650      * @param type the type of element that {@code s} is permitted to hold
3651      * @return a dynamically typesafe view of the specified sorted set
3652      * @since 1.5
3653      */
3654     public static <E> SortedSet<E> checkedSortedSet(SortedSet<E> s,
3655                                                     Class<E> type) {
3656         return new CheckedSortedSet<>(s, type);
3657     }
3658 
3659     /**
3660      * @serial include
3661      */
3662     static class CheckedSortedSet<E> extends CheckedSet<E>
3663         implements SortedSet<E>, Serializable
3664     {
3665         @java.io.Serial
3666         private static final long serialVersionUID = 1599911165492914959L;
3667 
3668         @SuppressWarnings("serial") // Conditionally serializable
3669         private final SortedSet<E> ss;
3670 
3671         CheckedSortedSet(SortedSet<E> s, Class<E> type) {
3672             super(s, type);
3673             ss = s;
3674         }
3675 
3676         public Comparator<? super E> comparator() { return ss.comparator(); }
3677         public E first()                   { return ss.first(); }
3678         public E last()                    { return ss.last(); }
3679 
3680         public SortedSet<E> subSet(E fromElement, E toElement) {
3681             return checkedSortedSet(ss.subSet(fromElement,toElement), type);
3682         }
3683         public SortedSet<E> headSet(E toElement) {
3684             return checkedSortedSet(ss.headSet(toElement), type);
3685         }
3686         public SortedSet<E> tailSet(E fromElement) {
3687             return checkedSortedSet(ss.tailSet(fromElement), type);
3688         }
3689     }
3690 
3691     /**
3692      * Returns a dynamically typesafe view of the specified navigable set.
3693      * Any attempt to insert an element of the wrong type will result in an
3694      * immediate {@link ClassCastException}.  Assuming a navigable set
3695      * contains no incorrectly typed elements prior to the time a
3696      * dynamically typesafe view is generated, and that all subsequent
3697      * access to the navigable set takes place through the view, it is
3698      * <em>guaranteed</em> that the navigable set cannot contain an incorrectly
3699      * typed element.
3700      *
3701      * <p>A discussion of the use of dynamically typesafe views may be
3702      * found in the documentation for the {@link #checkedCollection
3703      * checkedCollection} method.
3704      *
3705      * <p>The returned navigable set will be serializable if the specified
3706      * navigable set is serializable.
3707      *
3708      * <p>Since {@code null} is considered to be a value of any reference
3709      * type, the returned navigable set permits insertion of null elements
3710      * whenever the backing sorted set does.
3711      *
3712      * @param <E> the class of the objects in the set
3713      * @param s the navigable set for which a dynamically typesafe view is to be
3714      *          returned
3715      * @param type the type of element that {@code s} is permitted to hold
3716      * @return a dynamically typesafe view of the specified navigable set
3717      * @since 1.8
3718      */
3719     public static <E> NavigableSet<E> checkedNavigableSet(NavigableSet<E> s,
3720                                                     Class<E> type) {
3721         return new CheckedNavigableSet<>(s, type);
3722     }
3723 
3724     /**
3725      * @serial include
3726      */
3727     static class CheckedNavigableSet<E> extends CheckedSortedSet<E>
3728         implements NavigableSet<E>, Serializable
3729     {
3730         @java.io.Serial
3731         private static final long serialVersionUID = -5429120189805438922L;
3732 
3733         @SuppressWarnings("serial") // Conditionally serializable
3734         private final NavigableSet<E> ns;
3735 
3736         CheckedNavigableSet(NavigableSet<E> s, Class<E> type) {
3737             super(s, type);
3738             ns = s;
3739         }
3740 
3741         public E lower(E e)                             { return ns.lower(e); }
3742         public E floor(E e)                             { return ns.floor(e); }
3743         public E ceiling(E e)                         { return ns.ceiling(e); }
3744         public E higher(E e)                           { return ns.higher(e); }
3745         public E pollFirst()                         { return ns.pollFirst(); }
3746         public E pollLast()                            {return ns.pollLast(); }
3747         public NavigableSet<E> descendingSet()
3748                       { return checkedNavigableSet(ns.descendingSet(), type); }
3749         public Iterator<E> descendingIterator()
3750             {return checkedNavigableSet(ns.descendingSet(), type).iterator(); }
3751 
3752         public NavigableSet<E> subSet(E fromElement, E toElement) {
3753             return checkedNavigableSet(ns.subSet(fromElement, true, toElement, false), type);
3754         }
3755         public NavigableSet<E> headSet(E toElement) {
3756             return checkedNavigableSet(ns.headSet(toElement, false), type);
3757         }
3758         public NavigableSet<E> tailSet(E fromElement) {
3759             return checkedNavigableSet(ns.tailSet(fromElement, true), type);
3760         }
3761 
3762         public NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
3763             return checkedNavigableSet(ns.subSet(fromElement, fromInclusive, toElement, toInclusive), type);
3764         }
3765 
3766         public NavigableSet<E> headSet(E toElement, boolean inclusive) {
3767             return checkedNavigableSet(ns.headSet(toElement, inclusive), type);
3768         }
3769 
3770         public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
3771             return checkedNavigableSet(ns.tailSet(fromElement, inclusive), type);
3772         }
3773     }
3774 
3775     /**
3776      * Returns a dynamically typesafe view of the specified list.
3777      * Any attempt to insert an element of the wrong type will result in
3778      * an immediate {@link ClassCastException}.  Assuming a list contains
3779      * no incorrectly typed elements prior to the time a dynamically typesafe
3780      * view is generated, and that all subsequent access to the list
3781      * takes place through the view, it is <i>guaranteed</i> that the
3782      * list cannot contain an incorrectly typed element.
3783      *
3784      * <p>A discussion of the use of dynamically typesafe views may be
3785      * found in the documentation for the {@link #checkedCollection
3786      * checkedCollection} method.
3787      *
3788      * <p>The returned list will be serializable if the specified list
3789      * is serializable.
3790      *
3791      * <p>Since {@code null} is considered to be a value of any reference
3792      * type, the returned list permits insertion of null elements whenever
3793      * the backing list does.
3794      *
3795      * @param <E> the class of the objects in the list
3796      * @param list the list for which a dynamically typesafe view is to be
3797      *             returned
3798      * @param type the type of element that {@code list} is permitted to hold
3799      * @return a dynamically typesafe view of the specified list
3800      * @since 1.5
3801      */
3802     public static <E> List<E> checkedList(List<E> list, Class<E> type) {
3803         return (list instanceof RandomAccess ?
3804                 new CheckedRandomAccessList<>(list, type) :
3805                 new CheckedList<>(list, type));
3806     }
3807 
3808     /**
3809      * @serial include
3810      */
3811     static class CheckedList<E>
3812         extends CheckedCollection<E>
3813         implements List<E>
3814     {
3815         @java.io.Serial
3816         private static final long serialVersionUID = 65247728283967356L;
3817         @SuppressWarnings("serial") // Conditionally serializable
3818         final List<E> list;
3819 
3820         CheckedList(List<E> list, Class<E> type) {
3821             super(list, type);
3822             this.list = list;
3823         }
3824 
3825         public boolean equals(Object o)  { return o == this || list.equals(o); }
3826         public int hashCode()            { return list.hashCode(); }
3827         public E get(int index)          { return list.get(index); }
3828         public E remove(int index)       { return list.remove(index); }
3829         public int indexOf(Object o)     { return list.indexOf(o); }
3830         public int lastIndexOf(Object o) { return list.lastIndexOf(o); }
3831 
3832         public E set(int index, E element) {
3833             return list.set(index, typeCheck(element));
3834         }
3835 
3836         public void add(int index, E element) {
3837             list.add(index, typeCheck(element));
3838         }
3839 
3840         public boolean addAll(int index, Collection<? extends E> c) {
3841             return list.addAll(index, checkedCopyOf(c));
3842         }
3843         public ListIterator<E> listIterator()   { return listIterator(0); }
3844 
3845         public ListIterator<E> listIterator(final int index) {
3846             final ListIterator<E> i = list.listIterator(index);
3847 
3848             return new ListIterator<>() {
3849                 public boolean hasNext()     { return i.hasNext(); }
3850                 public E next()              { return i.next(); }
3851                 public boolean hasPrevious() { return i.hasPrevious(); }
3852                 public E previous()          { return i.previous(); }
3853                 public int nextIndex()       { return i.nextIndex(); }
3854                 public int previousIndex()   { return i.previousIndex(); }
3855                 public void remove()         {        i.remove(); }
3856 
3857                 public void set(E e) {
3858                     i.set(typeCheck(e));
3859                 }
3860 
3861                 public void add(E e) {
3862                     i.add(typeCheck(e));
3863                 }
3864 
3865                 @Override
3866                 public void forEachRemaining(Consumer<? super E> action) {
3867                     i.forEachRemaining(action);
3868                 }
3869             };
3870         }
3871 
3872         public List<E> subList(int fromIndex, int toIndex) {
3873             return new CheckedList<>(list.subList(fromIndex, toIndex), type);
3874         }
3875 
3876         /**
3877          * {@inheritDoc}
3878          *
3879          * @throws ClassCastException if the class of an element returned by the
3880          *         operator prevents it from being added to this collection. The
3881          *         exception may be thrown after some elements of the list have
3882          *         already been replaced.
3883          */
3884         @Override
3885         public void replaceAll(UnaryOperator<E> operator) {
3886             Objects.requireNonNull(operator);
3887             list.replaceAll(e -> typeCheck(operator.apply(e)));
3888         }
3889 
3890         @Override
3891         public void sort(Comparator<? super E> c) {
3892             list.sort(c);
3893         }
3894     }
3895 
3896     /**
3897      * @serial include
3898      */
3899     static class CheckedRandomAccessList<E> extends CheckedList<E>
3900                                             implements RandomAccess
3901     {
3902         @java.io.Serial
3903         private static final long serialVersionUID = 1638200125423088369L;
3904 
3905         CheckedRandomAccessList(List<E> list, Class<E> type) {
3906             super(list, type);
3907         }
3908 
3909         public List<E> subList(int fromIndex, int toIndex) {
3910             return new CheckedRandomAccessList<>(
3911                     list.subList(fromIndex, toIndex), type);
3912         }
3913     }
3914 
3915     /**
3916      * Returns a dynamically typesafe view of the specified map.
3917      * Any attempt to insert a mapping whose key or value have the wrong
3918      * type will result in an immediate {@link ClassCastException}.
3919      * Similarly, any attempt to modify the value currently associated with
3920      * a key will result in an immediate {@link ClassCastException},
3921      * whether the modification is attempted directly through the map
3922      * itself, or through a {@link Map.Entry} instance obtained from the
3923      * map's {@link Map#entrySet() entry set} view.
3924      *
3925      * <p>Assuming a map contains no incorrectly typed keys or values
3926      * prior to the time a dynamically typesafe view is generated, and
3927      * that all subsequent access to the map takes place through the view
3928      * (or one of its collection views), it is <i>guaranteed</i> that the
3929      * map cannot contain an incorrectly typed key or value.
3930      *
3931      * <p>A discussion of the use of dynamically typesafe views may be
3932      * found in the documentation for the {@link #checkedCollection
3933      * checkedCollection} method.
3934      *
3935      * <p>The returned map will be serializable if the specified map is
3936      * serializable.
3937      *
3938      * <p>Since {@code null} is considered to be a value of any reference
3939      * type, the returned map permits insertion of null keys or values
3940      * whenever the backing map does.
3941      *
3942      * @param <K> the class of the map keys
3943      * @param <V> the class of the map values
3944      * @param m the map for which a dynamically typesafe view is to be
3945      *          returned
3946      * @param keyType the type of key that {@code m} is permitted to hold
3947      * @param valueType the type of value that {@code m} is permitted to hold
3948      * @return a dynamically typesafe view of the specified map
3949      * @since 1.5
3950      */
3951     public static <K, V> Map<K, V> checkedMap(Map<K, V> m,
3952                                               Class<K> keyType,
3953                                               Class<V> valueType) {
3954         return new CheckedMap<>(m, keyType, valueType);
3955     }
3956 
3957 
3958     /**
3959      * @serial include
3960      */
3961     private static class CheckedMap<K,V>
3962         implements Map<K,V>, Serializable
3963     {
3964         @java.io.Serial
3965         private static final long serialVersionUID = 5742860141034234728L;
3966 
3967         @SuppressWarnings("serial") // Conditionally serializable
3968         private final Map<K, V> m;
3969         @SuppressWarnings("serial") // Conditionally serializable
3970         final Class<K> keyType;
3971         @SuppressWarnings("serial") // Conditionally serializable
3972         final Class<V> valueType;
3973 
3974         private void typeCheck(Object key, Object value) {
3975             if (key != null && !keyType.isInstance(key))
3976                 throw new ClassCastException(badKeyMsg(key));
3977 
3978             if (value != null && !valueType.isInstance(value))
3979                 throw new ClassCastException(badValueMsg(value));
3980         }
3981 
3982         private BiFunction<? super K, ? super V, ? extends V> typeCheck(
3983                 BiFunction<? super K, ? super V, ? extends V> func) {
3984             Objects.requireNonNull(func);
3985             return (k, v) -> {
3986                 V newValue = func.apply(k, v);
3987                 typeCheck(k, newValue);
3988                 return newValue;
3989             };
3990         }
3991 
3992         private String badKeyMsg(Object key) {
3993             return "Attempt to insert " + key.getClass() +
3994                     " key into map with key type " + keyType;
3995         }
3996 
3997         private String badValueMsg(Object value) {
3998             return "Attempt to insert " + value.getClass() +
3999                     " value into map with value type " + valueType;
4000         }
4001 
4002         CheckedMap(Map<K, V> m, Class<K> keyType, Class<V> valueType) {
4003             this.m = Objects.requireNonNull(m);
4004             this.keyType = Objects.requireNonNull(keyType);
4005             this.valueType = Objects.requireNonNull(valueType);
4006         }
4007 
4008         public int size()                      { return m.size(); }
4009         public boolean isEmpty()               { return m.isEmpty(); }
4010         public boolean containsKey(Object key) { return m.containsKey(key); }
4011         public boolean containsValue(Object v) { return m.containsValue(v); }
4012         public V get(Object key)               { return m.get(key); }
4013         public V remove(Object key)            { return m.remove(key); }
4014         public void clear()                    { m.clear(); }
4015         public Set<K> keySet()                 { return m.keySet(); }
4016         public Collection<V> values()          { return m.values(); }
4017         public boolean equals(Object o)        { return o == this || m.equals(o); }
4018         public int hashCode()                  { return m.hashCode(); }
4019         public String toString()               { return m.toString(); }
4020 
4021         public V put(K key, V value) {
4022             typeCheck(key, value);
4023             return m.put(key, value);
4024         }
4025 
4026         @SuppressWarnings("unchecked")
4027         public void putAll(Map<? extends K, ? extends V> t) {
4028             // Satisfy the following goals:
4029             // - good diagnostics in case of type mismatch
4030             // - all-or-nothing semantics
4031             // - protection from malicious t
4032             // - correct behavior if t is a concurrent map
4033             Object[] entries = t.entrySet().toArray();
4034             List<Map.Entry<K,V>> checked = new ArrayList<>(entries.length);
4035             for (Object o : entries) {
4036                 Map.Entry<?,?> e = (Map.Entry<?,?>) o;
4037                 Object k = e.getKey();
4038                 Object v = e.getValue();
4039                 typeCheck(k, v);
4040                 checked.add(
4041                         new AbstractMap.SimpleImmutableEntry<>((K)k, (V)v));
4042             }
4043             for (Map.Entry<K,V> e : checked)
4044                 m.put(e.getKey(), e.getValue());
4045         }
4046 
4047         private transient Set<Map.Entry<K,V>> entrySet;
4048 
4049         public Set<Map.Entry<K,V>> entrySet() {
4050             if (entrySet==null)
4051                 entrySet = new CheckedEntrySet<>(m.entrySet(), valueType);
4052             return entrySet;
4053         }
4054 
4055         // Override default methods in Map
4056         @Override
4057         public void forEach(BiConsumer<? super K, ? super V> action) {
4058             m.forEach(action);
4059         }
4060 
4061         @Override
4062         public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
4063             m.replaceAll(typeCheck(function));
4064         }
4065 
4066         @Override
4067         public V putIfAbsent(K key, V value) {
4068             typeCheck(key, value);
4069             return m.putIfAbsent(key, value);
4070         }
4071 
4072         @Override
4073         public boolean remove(Object key, Object value) {
4074             return m.remove(key, value);
4075         }
4076 
4077         @Override
4078         public boolean replace(K key, V oldValue, V newValue) {
4079             typeCheck(key, newValue);
4080             return m.replace(key, oldValue, newValue);
4081         }
4082 
4083         @Override
4084         public V replace(K key, V value) {
4085             typeCheck(key, value);
4086             return m.replace(key, value);
4087         }
4088 
4089         @Override
4090         public V computeIfAbsent(K key,
4091                 Function<? super K, ? extends V> mappingFunction) {
4092             Objects.requireNonNull(mappingFunction);
4093             return m.computeIfAbsent(key, k -> {
4094                 V value = mappingFunction.apply(k);
4095                 typeCheck(k, value);
4096                 return value;
4097             });
4098         }
4099 
4100         @Override
4101         public V computeIfPresent(K key,
4102                 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
4103             return m.computeIfPresent(key, typeCheck(remappingFunction));
4104         }
4105 
4106         @Override
4107         public V compute(K key,
4108                 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
4109             return m.compute(key, typeCheck(remappingFunction));
4110         }
4111 
4112         @Override
4113         public V merge(K key, V value,
4114                 BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
4115             Objects.requireNonNull(remappingFunction);
4116             return m.merge(key, value, (v1, v2) -> {
4117                 V newValue = remappingFunction.apply(v1, v2);
4118                 typeCheck(null, newValue);
4119                 return newValue;
4120             });
4121         }
4122 
4123         /**
4124          * We need this class in addition to CheckedSet as Map.Entry permits
4125          * modification of the backing Map via the setValue operation.  This
4126          * class is subtle: there are many possible attacks that must be
4127          * thwarted.
4128          *
4129          * @serial exclude
4130          */
4131         static class CheckedEntrySet<K,V> implements Set<Map.Entry<K,V>> {
4132             private final Set<Map.Entry<K,V>> s;
4133             private final Class<V> valueType;
4134 
4135             CheckedEntrySet(Set<Map.Entry<K, V>> s, Class<V> valueType) {
4136                 this.s = s;
4137                 this.valueType = valueType;
4138             }
4139 
4140             public int size()        { return s.size(); }
4141             public boolean isEmpty() { return s.isEmpty(); }
4142             public String toString() { return s.toString(); }
4143             public int hashCode()    { return s.hashCode(); }
4144             public void clear()      {        s.clear(); }
4145 
4146             public boolean add(Map.Entry<K, V> e) {
4147                 throw new UnsupportedOperationException();
4148             }
4149             public boolean addAll(Collection<? extends Map.Entry<K, V>> coll) {
4150                 throw new UnsupportedOperationException();
4151             }
4152 
4153             public Iterator<Map.Entry<K,V>> iterator() {
4154                 final Iterator<Map.Entry<K, V>> i = s.iterator();
4155 
4156                 return new Iterator<>() {
4157                     public boolean hasNext() { return i.hasNext(); }
4158                     public void remove()     { i.remove(); }
4159 
4160                     public Map.Entry<K,V> next() {
4161                         return checkedEntry(i.next(), valueType);
4162                     }
4163                     public void forEachRemaining(Consumer<? super Entry<K, V>> action) {
4164                         Objects.requireNonNull(action);
4165                         i.forEachRemaining(
4166                             e -> action.accept(checkedEntry(e, valueType)));
4167                     }
4168                 };
4169             }
4170 
4171             // Android-changed: Ignore IsInstanceOfClass warning. b/73288967, b/73344263.
4172             // @SuppressWarnings("unchecked")
4173             @SuppressWarnings({ "unchecked", "IsInstanceOfClass" })
4174             public Object[] toArray() {
4175                 Object[] source = s.toArray();
4176 
4177                 /*
4178                  * Ensure that we don't get an ArrayStoreException even if
4179                  * s.toArray returns an array of something other than Object
4180                  */
4181                 Object[] dest = (source.getClass() == Object[].class)
4182                     ? source
4183                     : new Object[source.length];
4184 
4185                 for (int i = 0; i < source.length; i++)
4186                     dest[i] = checkedEntry((Map.Entry<K,V>)source[i],
4187                                            valueType);
4188                 return dest;
4189             }
4190 
4191             @SuppressWarnings("unchecked")
4192             public <T> T[] toArray(T[] a) {
4193                 // We don't pass a to s.toArray, to avoid window of
4194                 // vulnerability wherein an unscrupulous multithreaded client
4195                 // could get his hands on raw (unwrapped) Entries from s.
4196                 T[] arr = s.toArray(a.length==0 ? a : Arrays.copyOf(a, 0));
4197 
4198                 for (int i=0; i<arr.length; i++)
4199                     arr[i] = (T) checkedEntry((Map.Entry<K,V>)arr[i],
4200                                               valueType);
4201                 if (arr.length > a.length)
4202                     return arr;
4203 
4204                 System.arraycopy(arr, 0, a, 0, arr.length);
4205                 if (a.length > arr.length)
4206                     a[arr.length] = null;
4207                 return a;
4208             }
4209 
4210             /**
4211              * This method is overridden to protect the backing set against
4212              * an object with a nefarious equals function that senses
4213              * that the equality-candidate is Map.Entry and calls its
4214              * setValue method.
4215              */
4216             public boolean contains(Object o) {
4217                 // Android-changed: (b/247094511) instanceof pattern variable is not yet supported.
4218                 /*
4219                 return o instanceof Map.Entry<?, ?> e
4220                         && s.contains((e instanceof CheckedEntry) ? e : checkedEntry(e, valueType));
4221                  */
4222                 if (!(o instanceof Map.Entry))
4223                     return false;
4224                 Map.Entry<?,?> e = (Map.Entry<?,?>) o;
4225                 return s.contains(
4226                         (e instanceof CheckedEntry) ? e : checkedEntry(e, valueType));
4227             }
4228 
4229             /**
4230              * The bulk collection methods are overridden to protect
4231              * against an unscrupulous collection whose contains(Object o)
4232              * method senses when o is a Map.Entry, and calls o.setValue.
4233              */
4234             public boolean containsAll(Collection<?> c) {
4235                 for (Object o : c)
4236                     if (!contains(o)) // Invokes safe contains() above
4237                         return false;
4238                 return true;
4239             }
4240 
4241             public boolean remove(Object o) {
4242                 if (!(o instanceof Map.Entry))
4243                     return false;
4244                 return s.remove(new AbstractMap.SimpleImmutableEntry
4245                                 <>((Map.Entry<?,?>)o));
4246             }
4247 
4248             public boolean removeAll(Collection<?> c) {
4249                 return batchRemove(c, false);
4250             }
4251             public boolean retainAll(Collection<?> c) {
4252                 return batchRemove(c, true);
4253             }
4254             private boolean batchRemove(Collection<?> c, boolean complement) {
4255                 Objects.requireNonNull(c);
4256                 boolean modified = false;
4257                 Iterator<Map.Entry<K,V>> it = iterator();
4258                 while (it.hasNext()) {
4259                     if (c.contains(it.next()) != complement) {
4260                         it.remove();
4261                         modified = true;
4262                     }
4263                 }
4264                 return modified;
4265             }
4266 
4267             public boolean equals(Object o) {
4268                 if (o == this)
4269                     return true;
4270                 // Android-changed: (b/247094511) instanceof pattern variable is not yet supported
4271                 /*
4272                 return o instanceof Set<?> that
4273                         && that.size() == s.size()
4274                         && containsAll(that); // Invokes safe containsAll() above
4275                  */
4276                 if (!(o instanceof Set))
4277                     return false;
4278                 Set<?> that = (Set<?>) o;
4279                 return that.size() == s.size()
4280                         && containsAll(that); // Invokes safe containsAll() above
4281             }
4282 
4283             static <K,V,T> CheckedEntry<K,V,T> checkedEntry(Map.Entry<K,V> e,
4284                                                             Class<T> valueType) {
4285                 return new CheckedEntry<>(e, valueType);
4286             }
4287 
4288             /**
4289              * This "wrapper class" serves two purposes: it prevents
4290              * the client from modifying the backing Map, by short-circuiting
4291              * the setValue method, and it protects the backing Map against
4292              * an ill-behaved Map.Entry that attempts to modify another
4293              * Map.Entry when asked to perform an equality check.
4294              */
4295             private static class CheckedEntry<K,V,T> implements Map.Entry<K,V> {
4296                 private final Map.Entry<K, V> e;
4297                 private final Class<T> valueType;
4298 
4299                 CheckedEntry(Map.Entry<K, V> e, Class<T> valueType) {
4300                     this.e = Objects.requireNonNull(e);
4301                     this.valueType = Objects.requireNonNull(valueType);
4302                 }
4303 
4304                 public K getKey()        { return e.getKey(); }
4305                 public V getValue()      { return e.getValue(); }
4306                 public int hashCode()    { return e.hashCode(); }
4307                 public String toString() { return e.toString(); }
4308 
4309                 public V setValue(V value) {
4310                     if (value != null && !valueType.isInstance(value))
4311                         throw new ClassCastException(badValueMsg(value));
4312                     return e.setValue(value);
4313                 }
4314 
4315                 private String badValueMsg(Object value) {
4316                     return "Attempt to insert " + value.getClass() +
4317                         " value into map with value type " + valueType;
4318                 }
4319 
4320                 public boolean equals(Object o) {
4321                     if (o == this)
4322                         return true;
4323                     if (!(o instanceof Map.Entry))
4324                         return false;
4325                     return e.equals(new AbstractMap.SimpleImmutableEntry
4326                                     <>((Map.Entry<?,?>)o));
4327                 }
4328             }
4329         }
4330     }
4331 
4332     /**
4333      * Returns a dynamically typesafe view of the specified sorted map.
4334      * Any attempt to insert a mapping whose key or value have the wrong
4335      * type will result in an immediate {@link ClassCastException}.
4336      * Similarly, any attempt to modify the value currently associated with
4337      * a key will result in an immediate {@link ClassCastException},
4338      * whether the modification is attempted directly through the map
4339      * itself, or through a {@link Map.Entry} instance obtained from the
4340      * map's {@link Map#entrySet() entry set} view.
4341      *
4342      * <p>Assuming a map contains no incorrectly typed keys or values
4343      * prior to the time a dynamically typesafe view is generated, and
4344      * that all subsequent access to the map takes place through the view
4345      * (or one of its collection views), it is <i>guaranteed</i> that the
4346      * map cannot contain an incorrectly typed key or value.
4347      *
4348      * <p>A discussion of the use of dynamically typesafe views may be
4349      * found in the documentation for the {@link #checkedCollection
4350      * checkedCollection} method.
4351      *
4352      * <p>The returned map will be serializable if the specified map is
4353      * serializable.
4354      *
4355      * <p>Since {@code null} is considered to be a value of any reference
4356      * type, the returned map permits insertion of null keys or values
4357      * whenever the backing map does.
4358      *
4359      * @param <K> the class of the map keys
4360      * @param <V> the class of the map values
4361      * @param m the map for which a dynamically typesafe view is to be
4362      *          returned
4363      * @param keyType the type of key that {@code m} is permitted to hold
4364      * @param valueType the type of value that {@code m} is permitted to hold
4365      * @return a dynamically typesafe view of the specified map
4366      * @since 1.5
4367      */
4368     public static <K,V> SortedMap<K,V> checkedSortedMap(SortedMap<K, V> m,
4369                                                         Class<K> keyType,
4370                                                         Class<V> valueType) {
4371         return new CheckedSortedMap<>(m, keyType, valueType);
4372     }
4373 
4374     /**
4375      * @serial include
4376      */
4377     static class CheckedSortedMap<K,V> extends CheckedMap<K,V>
4378         implements SortedMap<K,V>, Serializable
4379     {
4380         @java.io.Serial
4381         private static final long serialVersionUID = 1599671320688067438L;
4382 
4383         @SuppressWarnings("serial") // Conditionally serializable
4384         private final SortedMap<K, V> sm;
4385 
4386         CheckedSortedMap(SortedMap<K, V> m,
4387                          Class<K> keyType, Class<V> valueType) {
4388             super(m, keyType, valueType);
4389             sm = m;
4390         }
4391 
4392         public Comparator<? super K> comparator() { return sm.comparator(); }
4393         public K firstKey()                       { return sm.firstKey(); }
4394         public K lastKey()                        { return sm.lastKey(); }
4395 
4396         public SortedMap<K,V> subMap(K fromKey, K toKey) {
4397             return checkedSortedMap(sm.subMap(fromKey, toKey),
4398                                     keyType, valueType);
4399         }
4400         public SortedMap<K,V> headMap(K toKey) {
4401             return checkedSortedMap(sm.headMap(toKey), keyType, valueType);
4402         }
4403         public SortedMap<K,V> tailMap(K fromKey) {
4404             return checkedSortedMap(sm.tailMap(fromKey), keyType, valueType);
4405         }
4406     }
4407 
4408     /**
4409      * Returns a dynamically typesafe view of the specified navigable map.
4410      * Any attempt to insert a mapping whose key or value have the wrong
4411      * type will result in an immediate {@link ClassCastException}.
4412      * Similarly, any attempt to modify the value currently associated with
4413      * a key will result in an immediate {@link ClassCastException},
4414      * whether the modification is attempted directly through the map
4415      * itself, or through a {@link Map.Entry} instance obtained from the
4416      * map's {@link Map#entrySet() entry set} view.
4417      *
4418      * <p>Assuming a map contains no incorrectly typed keys or values
4419      * prior to the time a dynamically typesafe view is generated, and
4420      * that all subsequent access to the map takes place through the view
4421      * (or one of its collection views), it is <em>guaranteed</em> that the
4422      * map cannot contain an incorrectly typed key or value.
4423      *
4424      * <p>A discussion of the use of dynamically typesafe views may be
4425      * found in the documentation for the {@link #checkedCollection
4426      * checkedCollection} method.
4427      *
4428      * <p>The returned map will be serializable if the specified map is
4429      * serializable.
4430      *
4431      * <p>Since {@code null} is considered to be a value of any reference
4432      * type, the returned map permits insertion of null keys or values
4433      * whenever the backing map does.
4434      *
4435      * @param <K> type of map keys
4436      * @param <V> type of map values
4437      * @param m the map for which a dynamically typesafe view is to be
4438      *          returned
4439      * @param keyType the type of key that {@code m} is permitted to hold
4440      * @param valueType the type of value that {@code m} is permitted to hold
4441      * @return a dynamically typesafe view of the specified map
4442      * @since 1.8
4443      */
4444     public static <K,V> NavigableMap<K,V> checkedNavigableMap(NavigableMap<K, V> m,
4445                                                         Class<K> keyType,
4446                                                         Class<V> valueType) {
4447         return new CheckedNavigableMap<>(m, keyType, valueType);
4448     }
4449 
4450     /**
4451      * @serial include
4452      */
4453     static class CheckedNavigableMap<K,V> extends CheckedSortedMap<K,V>
4454         implements NavigableMap<K,V>, Serializable
4455     {
4456         @java.io.Serial
4457         private static final long serialVersionUID = -4852462692372534096L;
4458 
4459         @SuppressWarnings("serial") // Conditionally serializable
4460         private final NavigableMap<K, V> nm;
4461 
4462         CheckedNavigableMap(NavigableMap<K, V> m,
4463                          Class<K> keyType, Class<V> valueType) {
4464             super(m, keyType, valueType);
4465             nm = m;
4466         }
4467 
4468         public Comparator<? super K> comparator()   { return nm.comparator(); }
4469         public K firstKey()                           { return nm.firstKey(); }
4470         public K lastKey()                             { return nm.lastKey(); }
4471 
4472         public Entry<K, V> lowerEntry(K key) {
4473             Entry<K,V> lower = nm.lowerEntry(key);
4474             return (null != lower)
4475                 ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(lower, valueType)
4476                 : null;
4477         }
4478 
4479         public K lowerKey(K key)                   { return nm.lowerKey(key); }
4480 
4481         public Entry<K, V> floorEntry(K key) {
4482             Entry<K,V> floor = nm.floorEntry(key);
4483             return (null != floor)
4484                 ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(floor, valueType)
4485                 : null;
4486         }
4487 
4488         public K floorKey(K key)                   { return nm.floorKey(key); }
4489 
4490         public Entry<K, V> ceilingEntry(K key) {
4491             Entry<K,V> ceiling = nm.ceilingEntry(key);
4492             return (null != ceiling)
4493                 ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(ceiling, valueType)
4494                 : null;
4495         }
4496 
4497         public K ceilingKey(K key)               { return nm.ceilingKey(key); }
4498 
4499         public Entry<K, V> higherEntry(K key) {
4500             Entry<K,V> higher = nm.higherEntry(key);
4501             return (null != higher)
4502                 ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(higher, valueType)
4503                 : null;
4504         }
4505 
4506         public K higherKey(K key)                 { return nm.higherKey(key); }
4507 
4508         public Entry<K, V> firstEntry() {
4509             Entry<K,V> first = nm.firstEntry();
4510             return (null != first)
4511                 ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(first, valueType)
4512                 : null;
4513         }
4514 
4515         public Entry<K, V> lastEntry() {
4516             Entry<K,V> last = nm.lastEntry();
4517             return (null != last)
4518                 ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(last, valueType)
4519                 : null;
4520         }
4521 
4522         public Entry<K, V> pollFirstEntry() {
4523             Entry<K,V> entry = nm.pollFirstEntry();
4524             return (null == entry)
4525                 ? null
4526                 : new CheckedMap.CheckedEntrySet.CheckedEntry<>(entry, valueType);
4527         }
4528 
4529         public Entry<K, V> pollLastEntry() {
4530             Entry<K,V> entry = nm.pollLastEntry();
4531             return (null == entry)
4532                 ? null
4533                 : new CheckedMap.CheckedEntrySet.CheckedEntry<>(entry, valueType);
4534         }
4535 
4536         public NavigableMap<K, V> descendingMap() {
4537             return checkedNavigableMap(nm.descendingMap(), keyType, valueType);
4538         }
4539 
4540         public NavigableSet<K> keySet() {
4541             return navigableKeySet();
4542         }
4543 
4544         public NavigableSet<K> navigableKeySet() {
4545             return checkedNavigableSet(nm.navigableKeySet(), keyType);
4546         }
4547 
4548         public NavigableSet<K> descendingKeySet() {
4549             return checkedNavigableSet(nm.descendingKeySet(), keyType);
4550         }
4551 
4552         @Override
4553         public NavigableMap<K,V> subMap(K fromKey, K toKey) {
4554             return checkedNavigableMap(nm.subMap(fromKey, true, toKey, false),
4555                                     keyType, valueType);
4556         }
4557 
4558         @Override
4559         public NavigableMap<K,V> headMap(K toKey) {
4560             return checkedNavigableMap(nm.headMap(toKey, false), keyType, valueType);
4561         }
4562 
4563         @Override
4564         public NavigableMap<K,V> tailMap(K fromKey) {
4565             return checkedNavigableMap(nm.tailMap(fromKey, true), keyType, valueType);
4566         }
4567 
4568         public NavigableMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
4569             return checkedNavigableMap(nm.subMap(fromKey, fromInclusive, toKey, toInclusive), keyType, valueType);
4570         }
4571 
4572         public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
4573             return checkedNavigableMap(nm.headMap(toKey, inclusive), keyType, valueType);
4574         }
4575 
4576         public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
4577             return checkedNavigableMap(nm.tailMap(fromKey, inclusive), keyType, valueType);
4578         }
4579     }
4580 
4581     // Empty collections
4582 
4583     /**
4584      * Returns an iterator that has no elements.  More precisely,
4585      *
4586      * <ul>
4587      * <li>{@link Iterator#hasNext hasNext} always returns {@code
4588      * false}.</li>
4589      * <li>{@link Iterator#next next} always throws {@link
4590      * NoSuchElementException}.</li>
4591      * <li>{@link Iterator#remove remove} always throws {@link
4592      * IllegalStateException}.</li>
4593      * </ul>
4594      *
4595      * <p>Implementations of this method are permitted, but not
4596      * required, to return the same object from multiple invocations.
4597      *
4598      * @param <T> type of elements, if there were any, in the iterator
4599      * @return an empty iterator
4600      * @since 1.7
4601      */
4602     @SuppressWarnings("unchecked")
4603     public static <T> Iterator<T> emptyIterator() {
4604         return (Iterator<T>) EmptyIterator.EMPTY_ITERATOR;
4605     }
4606 
4607     private static class EmptyIterator<E> implements Iterator<E> {
4608         static final EmptyIterator<Object> EMPTY_ITERATOR
4609             = new EmptyIterator<>();
4610 
4611         public boolean hasNext() { return false; }
4612         public E next() { throw new NoSuchElementException(); }
4613         public void remove() { throw new IllegalStateException(); }
4614         @Override
4615         public void forEachRemaining(Consumer<? super E> action) {
4616             Objects.requireNonNull(action);
4617         }
4618     }
4619 
4620     /**
4621      * Returns a list iterator that has no elements.  More precisely,
4622      *
4623      * <ul>
4624      * <li>{@link Iterator#hasNext hasNext} and {@link
4625      * ListIterator#hasPrevious hasPrevious} always return {@code
4626      * false}.</li>
4627      * <li>{@link Iterator#next next} and {@link ListIterator#previous
4628      * previous} always throw {@link NoSuchElementException}.</li>
4629      * <li>{@link Iterator#remove remove} and {@link ListIterator#set
4630      * set} always throw {@link IllegalStateException}.</li>
4631      * <li>{@link ListIterator#add add} always throws {@link
4632      * UnsupportedOperationException}.</li>
4633      * <li>{@link ListIterator#nextIndex nextIndex} always returns
4634      * {@code 0}.</li>
4635      * <li>{@link ListIterator#previousIndex previousIndex} always
4636      * returns {@code -1}.</li>
4637      * </ul>
4638      *
4639      * <p>Implementations of this method are permitted, but not
4640      * required, to return the same object from multiple invocations.
4641      *
4642      * @param <T> type of elements, if there were any, in the iterator
4643      * @return an empty list iterator
4644      * @since 1.7
4645      */
4646     @SuppressWarnings("unchecked")
4647     public static <T> ListIterator<T> emptyListIterator() {
4648         return (ListIterator<T>) EmptyListIterator.EMPTY_ITERATOR;
4649     }
4650 
4651     private static class EmptyListIterator<E>
4652         extends EmptyIterator<E>
4653         implements ListIterator<E>
4654     {
4655         static final EmptyListIterator<Object> EMPTY_ITERATOR
4656             = new EmptyListIterator<>();
4657 
4658         public boolean hasPrevious() { return false; }
4659         public E previous() { throw new NoSuchElementException(); }
4660         public int nextIndex()     { return 0; }
4661         public int previousIndex() { return -1; }
4662         public void set(E e) { throw new IllegalStateException(); }
4663         public void add(E e) { throw new UnsupportedOperationException(); }
4664     }
4665 
4666     /**
4667      * Returns an enumeration that has no elements.  More precisely,
4668      *
4669      * <ul>
4670      * <li>{@link Enumeration#hasMoreElements hasMoreElements} always
4671      * returns {@code false}.</li>
4672      * <li> {@link Enumeration#nextElement nextElement} always throws
4673      * {@link NoSuchElementException}.</li>
4674      * </ul>
4675      *
4676      * <p>Implementations of this method are permitted, but not
4677      * required, to return the same object from multiple invocations.
4678      *
4679      * @param  <T> the class of the objects in the enumeration
4680      * @return an empty enumeration
4681      * @since 1.7
4682      */
4683     @SuppressWarnings("unchecked")
4684     public static <T> Enumeration<T> emptyEnumeration() {
4685         return (Enumeration<T>) EmptyEnumeration.EMPTY_ENUMERATION;
4686     }
4687 
4688     private static class EmptyEnumeration<E> implements Enumeration<E> {
4689         static final EmptyEnumeration<Object> EMPTY_ENUMERATION
4690             = new EmptyEnumeration<>();
4691 
4692         public boolean hasMoreElements() { return false; }
4693         public E nextElement() { throw new NoSuchElementException(); }
4694         public Iterator<E> asIterator() { return emptyIterator(); }
4695     }
4696 
4697     /**
4698      * The empty set (immutable).  This set is serializable.
4699      *
4700      * @see #emptySet()
4701      */
4702     @SuppressWarnings("rawtypes")
4703     public static final Set EMPTY_SET = new EmptySet<>();
4704 
4705     /**
4706      * Returns an empty set (immutable).  This set is serializable.
4707      * Unlike the like-named field, this method is parameterized.
4708      *
4709      * <p>This example illustrates the type-safe way to obtain an empty set:
4710      * <pre>
4711      *     Set&lt;String&gt; s = Collections.emptySet();
4712      * </pre>
4713      * @implNote Implementations of this method need not create a separate
4714      * {@code Set} object for each call.  Using this method is likely to have
4715      * comparable cost to using the like-named field.  (Unlike this method, the
4716      * field does not provide type safety.)
4717      *
4718      * @param  <T> the class of the objects in the set
4719      * @return the empty set
4720      *
4721      * @see #EMPTY_SET
4722      * @since 1.5
4723      */
4724     @SuppressWarnings("unchecked")
4725     public static final <T> Set<T> emptySet() {
4726         return (Set<T>) EMPTY_SET;
4727     }
4728 
4729     /**
4730      * @serial include
4731      */
4732     private static class EmptySet<E>
4733         extends AbstractSet<E>
4734         implements Serializable
4735     {
4736         @java.io.Serial
4737         private static final long serialVersionUID = 1582296315990362920L;
4738 
4739         public Iterator<E> iterator() { return emptyIterator(); }
4740 
4741         public int size() {return 0;}
4742         public boolean isEmpty() {return true;}
4743         public void clear() {}
4744 
4745         public boolean contains(Object obj) {return false;}
4746         public boolean containsAll(Collection<?> c) { return c.isEmpty(); }
4747 
4748         public Object[] toArray() { return new Object[0]; }
4749 
4750         public <T> T[] toArray(T[] a) {
4751             if (a.length > 0)
4752                 a[0] = null;
4753             return a;
4754         }
4755 
4756         // Override default methods in Collection
4757         @Override
4758         public void forEach(Consumer<? super E> action) {
4759             Objects.requireNonNull(action);
4760         }
4761         @Override
4762         public boolean removeIf(Predicate<? super E> filter) {
4763             Objects.requireNonNull(filter);
4764             return false;
4765         }
4766         @Override
4767         public Spliterator<E> spliterator() { return Spliterators.emptySpliterator(); }
4768 
4769         // Preserves singleton property
4770         @java.io.Serial
4771         private Object readResolve() {
4772             return EMPTY_SET;
4773         }
4774 
4775         @Override
4776         public int hashCode() {
4777             return 0;
4778         }
4779     }
4780 
4781     /**
4782      * Returns an empty sorted set (immutable).  This set is serializable.
4783      *
4784      * <p>This example illustrates the type-safe way to obtain an empty
4785      * sorted set:
4786      * <pre> {@code
4787      *     SortedSet<String> s = Collections.emptySortedSet();
4788      * }</pre>
4789      *
4790      * @implNote Implementations of this method need not create a separate
4791      * {@code SortedSet} object for each call.
4792      *
4793      * @param <E> type of elements, if there were any, in the set
4794      * @return the empty sorted set
4795      * @since 1.8
4796      */
4797     @SuppressWarnings("unchecked")
4798     public static <E> SortedSet<E> emptySortedSet() {
4799         return (SortedSet<E>) UnmodifiableNavigableSet.EMPTY_NAVIGABLE_SET;
4800     }
4801 
4802     /**
4803      * Returns an empty navigable set (immutable).  This set is serializable.
4804      *
4805      * <p>This example illustrates the type-safe way to obtain an empty
4806      * navigable set:
4807      * <pre> {@code
4808      *     NavigableSet<String> s = Collections.emptyNavigableSet();
4809      * }</pre>
4810      *
4811      * @implNote Implementations of this method need not
4812      * create a separate {@code NavigableSet} object for each call.
4813      *
4814      * @param <E> type of elements, if there were any, in the set
4815      * @return the empty navigable set
4816      * @since 1.8
4817      */
4818     @SuppressWarnings("unchecked")
4819     public static <E> NavigableSet<E> emptyNavigableSet() {
4820         return (NavigableSet<E>) UnmodifiableNavigableSet.EMPTY_NAVIGABLE_SET;
4821     }
4822 
4823     /**
4824      * The empty list (immutable).  This list is serializable.
4825      *
4826      * @see #emptyList()
4827      */
4828     @SuppressWarnings("rawtypes")
4829     public static final List EMPTY_LIST = new EmptyList<>();
4830 
4831     /**
4832      * Returns an empty list (immutable).  This list is serializable.
4833      *
4834      * <p>This example illustrates the type-safe way to obtain an empty list:
4835      * <pre>
4836      *     List&lt;String&gt; s = Collections.emptyList();
4837      * </pre>
4838      *
4839      * @implNote
4840      * Implementations of this method need not create a separate {@code List}
4841      * object for each call.   Using this method is likely to have comparable
4842      * cost to using the like-named field.  (Unlike this method, the field does
4843      * not provide type safety.)
4844      *
4845      * @param <T> type of elements, if there were any, in the list
4846      * @return an empty immutable list
4847      *
4848      * @see #EMPTY_LIST
4849      * @since 1.5
4850      */
4851     @SuppressWarnings("unchecked")
4852     public static final <T> List<T> emptyList() {
4853         return (List<T>) EMPTY_LIST;
4854     }
4855 
4856     /**
4857      * @serial include
4858      */
4859     private static class EmptyList<E>
4860         extends AbstractList<E>
4861         implements RandomAccess, Serializable {
4862         @java.io.Serial
4863         private static final long serialVersionUID = 8842843931221139166L;
4864 
4865         public Iterator<E> iterator() {
4866             return emptyIterator();
4867         }
4868         public ListIterator<E> listIterator() {
4869             return emptyListIterator();
4870         }
4871 
4872         public int size() {return 0;}
4873         public boolean isEmpty() {return true;}
4874         public void clear() {}
4875 
4876         public boolean contains(Object obj) {return false;}
4877         public boolean containsAll(Collection<?> c) { return c.isEmpty(); }
4878 
4879         public Object[] toArray() { return new Object[0]; }
4880 
4881         public <T> T[] toArray(T[] a) {
4882             if (a.length > 0)
4883                 a[0] = null;
4884             return a;
4885         }
4886 
4887         public E get(int index) {
4888             throw new IndexOutOfBoundsException("Index: "+index);
4889         }
4890 
4891         public boolean equals(Object o) {
4892             return (o instanceof List) && ((List<?>)o).isEmpty();
4893         }
4894 
4895         public int hashCode() { return 1; }
4896 
4897         @Override
4898         public boolean removeIf(Predicate<? super E> filter) {
4899             Objects.requireNonNull(filter);
4900             return false;
4901         }
4902         @Override
4903         public void replaceAll(UnaryOperator<E> operator) {
4904             Objects.requireNonNull(operator);
4905         }
4906         @Override
4907         public void sort(Comparator<? super E> c) {
4908         }
4909 
4910         // Override default methods in Collection
4911         @Override
4912         public void forEach(Consumer<? super E> action) {
4913             Objects.requireNonNull(action);
4914         }
4915 
4916         @Override
4917         public Spliterator<E> spliterator() { return Spliterators.emptySpliterator(); }
4918 
4919         // Preserves singleton property
4920         @java.io.Serial
4921         private Object readResolve() {
4922             return EMPTY_LIST;
4923         }
4924     }
4925 
4926     /**
4927      * The empty map (immutable).  This map is serializable.
4928      *
4929      * @see #emptyMap()
4930      * @since 1.3
4931      */
4932     @SuppressWarnings("rawtypes")
4933     public static final Map EMPTY_MAP = new EmptyMap<>();
4934 
4935     /**
4936      * Returns an empty map (immutable).  This map is serializable.
4937      *
4938      * <p>This example illustrates the type-safe way to obtain an empty map:
4939      * <pre>
4940      *     Map&lt;String, Date&gt; s = Collections.emptyMap();
4941      * </pre>
4942      * @implNote Implementations of this method need not create a separate
4943      * {@code Map} object for each call.  Using this method is likely to have
4944      * comparable cost to using the like-named field.  (Unlike this method, the
4945      * field does not provide type safety.)
4946      *
4947      * @param <K> the class of the map keys
4948      * @param <V> the class of the map values
4949      * @return an empty map
4950      * @see #EMPTY_MAP
4951      * @since 1.5
4952      */
4953     @SuppressWarnings("unchecked")
4954     public static final <K,V> Map<K,V> emptyMap() {
4955         return (Map<K,V>) EMPTY_MAP;
4956     }
4957 
4958     /**
4959      * Returns an empty sorted map (immutable).  This map is serializable.
4960      *
4961      * <p>This example illustrates the type-safe way to obtain an empty map:
4962      * <pre> {@code
4963      *     SortedMap<String, Date> s = Collections.emptySortedMap();
4964      * }</pre>
4965      *
4966      * @implNote Implementations of this method need not create a separate
4967      * {@code SortedMap} object for each call.
4968      *
4969      * @param <K> the class of the map keys
4970      * @param <V> the class of the map values
4971      * @return an empty sorted map
4972      * @since 1.8
4973      */
4974     @SuppressWarnings("unchecked")
4975     public static final <K,V> SortedMap<K,V> emptySortedMap() {
4976         return (SortedMap<K,V>) UnmodifiableNavigableMap.EMPTY_NAVIGABLE_MAP;
4977     }
4978 
4979     /**
4980      * Returns an empty navigable map (immutable).  This map is serializable.
4981      *
4982      * <p>This example illustrates the type-safe way to obtain an empty map:
4983      * <pre> {@code
4984      *     NavigableMap<String, Date> s = Collections.emptyNavigableMap();
4985      * }</pre>
4986      *
4987      * @implNote Implementations of this method need not create a separate
4988      * {@code NavigableMap} object for each call.
4989      *
4990      * @param <K> the class of the map keys
4991      * @param <V> the class of the map values
4992      * @return an empty navigable map
4993      * @since 1.8
4994      */
4995     @SuppressWarnings("unchecked")
4996     public static final <K,V> NavigableMap<K,V> emptyNavigableMap() {
4997         return (NavigableMap<K,V>) UnmodifiableNavigableMap.EMPTY_NAVIGABLE_MAP;
4998     }
4999 
5000     /**
5001      * @serial include
5002      */
5003     private static class EmptyMap<K,V>
5004         extends AbstractMap<K,V>
5005         implements Serializable
5006     {
5007         @java.io.Serial
5008         private static final long serialVersionUID = 6428348081105594320L;
5009 
5010         public int size()                          {return 0;}
5011         public boolean isEmpty()                   {return true;}
5012         public void clear()                        {}
5013         public boolean containsKey(Object key)     {return false;}
5014         public boolean containsValue(Object value) {return false;}
5015         public V get(Object key)                   {return null;}
5016         public Set<K> keySet()                     {return emptySet();}
5017         public Collection<V> values()              {return emptySet();}
5018         public Set<Map.Entry<K,V>> entrySet()      {return emptySet();}
5019 
5020         public boolean equals(Object o) {
5021             return (o instanceof Map) && ((Map<?,?>)o).isEmpty();
5022         }
5023 
5024         public int hashCode()                      {return 0;}
5025 
5026         // Override default methods in Map
5027         @Override
5028         public V getOrDefault(Object k, V defaultValue) {
5029             return defaultValue;
5030         }
5031 
5032         @Override
5033         public void forEach(BiConsumer<? super K, ? super V> action) {
5034             Objects.requireNonNull(action);
5035         }
5036 
5037         @Override
5038         public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
5039             Objects.requireNonNull(function);
5040         }
5041 
5042         @Override
5043         public V putIfAbsent(K key, V value) {
5044             throw new UnsupportedOperationException();
5045         }
5046 
5047         @Override
5048         public boolean remove(Object key, Object value) {
5049             throw new UnsupportedOperationException();
5050         }
5051 
5052         @Override
5053         public boolean replace(K key, V oldValue, V newValue) {
5054             throw new UnsupportedOperationException();
5055         }
5056 
5057         @Override
5058         public V replace(K key, V value) {
5059             throw new UnsupportedOperationException();
5060         }
5061 
5062         @Override
5063         public V computeIfAbsent(K key,
5064                 Function<? super K, ? extends V> mappingFunction) {
5065             throw new UnsupportedOperationException();
5066         }
5067 
5068         @Override
5069         public V computeIfPresent(K key,
5070                 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
5071             throw new UnsupportedOperationException();
5072         }
5073 
5074         @Override
5075         public V compute(K key,
5076                 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
5077             throw new UnsupportedOperationException();
5078         }
5079 
5080         @Override
5081         public V merge(K key, V value,
5082                 BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
5083             throw new UnsupportedOperationException();
5084         }
5085 
5086         // Preserves singleton property
5087         @java.io.Serial
5088         private Object readResolve() {
5089             return EMPTY_MAP;
5090         }
5091     }
5092 
5093     // Singleton collections
5094 
5095     /**
5096      * Returns an immutable set containing only the specified object.
5097      * The returned set is serializable.
5098      *
5099      * @param  <T> the class of the objects in the set
5100      * @param o the sole object to be stored in the returned set.
5101      * @return an immutable set containing only the specified object.
5102      */
5103     public static <T> Set<T> singleton(T o) {
5104         return new SingletonSet<>(o);
5105     }
5106 
5107     static <E> Iterator<E> singletonIterator(final E e) {
5108         return new Iterator<>() {
5109             private boolean hasNext = true;
5110             public boolean hasNext() {
5111                 return hasNext;
5112             }
5113             public E next() {
5114                 if (hasNext) {
5115                     hasNext = false;
5116                     return e;
5117                 }
5118                 throw new NoSuchElementException();
5119             }
5120             public void remove() {
5121                 throw new UnsupportedOperationException();
5122             }
5123             @Override
5124             public void forEachRemaining(Consumer<? super E> action) {
5125                 Objects.requireNonNull(action);
5126                 if (hasNext) {
5127                     hasNext = false;
5128                     action.accept(e);
5129                 }
5130             }
5131         };
5132     }
5133 
5134     /**
5135      * Creates a {@code Spliterator} with only the specified element
5136      *
5137      * @param <T> Type of elements
5138      * @return A singleton {@code Spliterator}
5139      */
5140     static <T> Spliterator<T> singletonSpliterator(final T element) {
5141         return new Spliterator<>() {
5142             long est = 1;
5143 
5144             @Override
5145             public Spliterator<T> trySplit() {
5146                 return null;
5147             }
5148 
5149             @Override
5150             public boolean tryAdvance(Consumer<? super T> consumer) {
5151                 Objects.requireNonNull(consumer);
5152                 if (est > 0) {
5153                     est--;
5154                     consumer.accept(element);
5155                     return true;
5156                 }
5157                 return false;
5158             }
5159 
5160             @Override
5161             public void forEachRemaining(Consumer<? super T> consumer) {
5162                 tryAdvance(consumer);
5163             }
5164 
5165             @Override
5166             public long estimateSize() {
5167                 return est;
5168             }
5169 
5170             @Override
5171             public int characteristics() {
5172                 int value = (element != null) ? Spliterator.NONNULL : 0;
5173 
5174                 return value | Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.IMMUTABLE |
5175                        Spliterator.DISTINCT | Spliterator.ORDERED;
5176             }
5177         };
5178     }
5179 
5180     /**
5181      * @serial include
5182      */
5183     private static class SingletonSet<E>
5184         extends AbstractSet<E>
5185         implements Serializable
5186     {
5187         @java.io.Serial
5188         private static final long serialVersionUID = 3193687207550431679L;
5189 
5190         @SuppressWarnings("serial") // Conditionally serializable
5191         private final E element;
5192 
5193         SingletonSet(E e) {element = e;}
5194 
5195         public Iterator<E> iterator() {
5196             return singletonIterator(element);
5197         }
5198 
5199         public int size() {return 1;}
5200 
5201         public boolean contains(Object o) {return eq(o, element);}
5202 
5203         // Override default methods for Collection
5204         @Override
5205         public void forEach(Consumer<? super E> action) {
5206             action.accept(element);
5207         }
5208         @Override
5209         public Spliterator<E> spliterator() {
5210             return singletonSpliterator(element);
5211         }
5212         @Override
5213         public boolean removeIf(Predicate<? super E> filter) {
5214             throw new UnsupportedOperationException();
5215         }
5216         @Override
5217         public int hashCode() {
5218             return Objects.hashCode(element);
5219         }
5220     }
5221 
5222     /**
5223      * Returns an immutable list containing only the specified object.
5224      * The returned list is serializable.
5225      *
5226      * @param  <T> the class of the objects in the list
5227      * @param o the sole object to be stored in the returned list.
5228      * @return an immutable list containing only the specified object.
5229      * @since 1.3
5230      */
5231     public static <T> List<T> singletonList(T o) {
5232         return new SingletonList<>(o);
5233     }
5234 
5235     /**
5236      * @serial include
5237      */
5238     private static class SingletonList<E>
5239         extends AbstractList<E>
5240         implements RandomAccess, Serializable {
5241 
5242         @java.io.Serial
5243         private static final long serialVersionUID = 3093736618740652951L;
5244 
5245         @SuppressWarnings("serial") // Conditionally serializable
5246         private final E element;
5247 
5248         SingletonList(E obj)                {element = obj;}
5249 
5250         public Iterator<E> iterator() {
5251             return singletonIterator(element);
5252         }
5253 
5254         public int size()                   {return 1;}
5255 
5256         public boolean contains(Object obj) {return eq(obj, element);}
5257 
5258         public E get(int index) {
5259             if (index != 0)
5260               throw new IndexOutOfBoundsException("Index: "+index+", Size: 1");
5261             return element;
5262         }
5263 
5264         // Override default methods for Collection
5265         @Override
5266         public void forEach(Consumer<? super E> action) {
5267             action.accept(element);
5268         }
5269         @Override
5270         public boolean removeIf(Predicate<? super E> filter) {
5271             throw new UnsupportedOperationException();
5272         }
5273         @Override
5274         public void replaceAll(UnaryOperator<E> operator) {
5275             throw new UnsupportedOperationException();
5276         }
5277         @Override
5278         public void sort(Comparator<? super E> c) {
5279         }
5280         @Override
5281         public Spliterator<E> spliterator() {
5282             return singletonSpliterator(element);
5283         }
5284         @Override
5285         public int hashCode() {
5286             return 31 + Objects.hashCode(element);
5287         }
5288     }
5289 
5290     /**
5291      * Returns an immutable map, mapping only the specified key to the
5292      * specified value.  The returned map is serializable.
5293      *
5294      * @param <K> the class of the map keys
5295      * @param <V> the class of the map values
5296      * @param key the sole key to be stored in the returned map.
5297      * @param value the value to which the returned map maps {@code key}.
5298      * @return an immutable map containing only the specified key-value
5299      *         mapping.
5300      * @since 1.3
5301      */
5302     public static <K,V> Map<K,V> singletonMap(K key, V value) {
5303         return new SingletonMap<>(key, value);
5304     }
5305 
5306     /**
5307      * @serial include
5308      */
5309     private static class SingletonMap<K,V>
5310           extends AbstractMap<K,V>
5311           implements Serializable {
5312         @java.io.Serial
5313         private static final long serialVersionUID = -6979724477215052911L;
5314 
5315         @SuppressWarnings("serial") // Conditionally serializable
5316         private final K k;
5317         @SuppressWarnings("serial") // Conditionally serializable
5318         private final V v;
5319 
5320         SingletonMap(K key, V value) {
5321             k = key;
5322             v = value;
5323         }
5324 
5325         public int size()                                           {return 1;}
5326         public boolean isEmpty()                                {return false;}
5327         public boolean containsKey(Object key)             {return eq(key, k);}
5328         public boolean containsValue(Object value)       {return eq(value, v);}
5329         public V get(Object key)              {return (eq(key, k) ? v : null);}
5330 
5331         private transient Set<K> keySet;
5332         private transient Set<Map.Entry<K,V>> entrySet;
5333         private transient Collection<V> values;
5334 
5335         public Set<K> keySet() {
5336             if (keySet==null)
5337                 keySet = singleton(k);
5338             return keySet;
5339         }
5340 
5341         public Set<Map.Entry<K,V>> entrySet() {
5342             if (entrySet==null)
5343                 entrySet = Collections.singleton(
5344                     new SimpleImmutableEntry<>(k, v));
5345             return entrySet;
5346         }
5347 
5348         public Collection<V> values() {
5349             if (values==null)
5350                 values = singleton(v);
5351             return values;
5352         }
5353 
5354         // Override default methods in Map
5355         @Override
5356         public V getOrDefault(Object key, V defaultValue) {
5357             return eq(key, k) ? v : defaultValue;
5358         }
5359 
5360         @Override
5361         public void forEach(BiConsumer<? super K, ? super V> action) {
5362             action.accept(k, v);
5363         }
5364 
5365         @Override
5366         public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
5367             throw new UnsupportedOperationException();
5368         }
5369 
5370         @Override
5371         public V putIfAbsent(K key, V value) {
5372             throw new UnsupportedOperationException();
5373         }
5374 
5375         @Override
5376         public boolean remove(Object key, Object value) {
5377             throw new UnsupportedOperationException();
5378         }
5379 
5380         @Override
5381         public boolean replace(K key, V oldValue, V newValue) {
5382             throw new UnsupportedOperationException();
5383         }
5384 
5385         @Override
5386         public V replace(K key, V value) {
5387             throw new UnsupportedOperationException();
5388         }
5389 
5390         @Override
5391         public V computeIfAbsent(K key,
5392                 Function<? super K, ? extends V> mappingFunction) {
5393             throw new UnsupportedOperationException();
5394         }
5395 
5396         @Override
5397         public V computeIfPresent(K key,
5398                 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
5399             throw new UnsupportedOperationException();
5400         }
5401 
5402         @Override
5403         public V compute(K key,
5404                 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
5405             throw new UnsupportedOperationException();
5406         }
5407 
5408         @Override
5409         public V merge(K key, V value,
5410                 BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
5411             throw new UnsupportedOperationException();
5412         }
5413 
5414         @Override
5415         public int hashCode() {
5416             return Objects.hashCode(k) ^ Objects.hashCode(v);
5417         }
5418     }
5419 
5420     // Miscellaneous
5421 
5422     /**
5423      * Returns an immutable list consisting of {@code n} copies of the
5424      * specified object.  The newly allocated data object is tiny (it contains
5425      * a single reference to the data object).  This method is useful in
5426      * combination with the {@code List.addAll} method to grow lists.
5427      * The returned list is serializable.
5428      *
5429      * @param  <T> the class of the object to copy and of the objects
5430      *         in the returned list.
5431      * @param  n the number of elements in the returned list.
5432      * @param  o the element to appear repeatedly in the returned list.
5433      * @return an immutable list consisting of {@code n} copies of the
5434      *         specified object.
5435      * @throws IllegalArgumentException if {@code n < 0}
5436      * @see    List#addAll(Collection)
5437      * @see    List#addAll(int, Collection)
5438      */
5439     public static <T> List<T> nCopies(int n, T o) {
5440         if (n < 0)
5441             throw new IllegalArgumentException("List length = " + n);
5442         return new CopiesList<>(n, o);
5443     }
5444 
5445     /**
5446      * @serial include
5447      */
5448     private static class CopiesList<E>
5449         extends AbstractList<E>
5450         implements RandomAccess, Serializable
5451     {
5452         @java.io.Serial
5453         private static final long serialVersionUID = 2739099268398711800L;
5454 
5455         final int n;
5456         @SuppressWarnings("serial") // Conditionally serializable
5457         final E element;
5458 
5459         CopiesList(int n, E e) {
5460             assert n >= 0;
5461             this.n = n;
5462             element = e;
5463         }
5464 
5465         public int size() {
5466             return n;
5467         }
5468 
5469         public boolean contains(Object obj) {
5470             return n != 0 && eq(obj, element);
5471         }
5472 
5473         public int indexOf(Object o) {
5474             return contains(o) ? 0 : -1;
5475         }
5476 
5477         public int lastIndexOf(Object o) {
5478             return contains(o) ? n - 1 : -1;
5479         }
5480 
5481         public E get(int index) {
5482             Objects.checkIndex(index, n);
5483             return element;
5484         }
5485 
5486         @Override
5487         public void forEach(Consumer<? super E> action) {
5488             Objects.requireNonNull(action);
5489             int n = this.n;
5490             E element = this.element;
5491             for (int i = 0; i < n; i++) {
5492                 action.accept(element);
5493             }
5494         }
5495 
5496         public Object[] toArray() {
5497             final Object[] a = new Object[n];
5498             if (element != null)
5499                 Arrays.fill(a, 0, n, element);
5500             return a;
5501         }
5502 
5503         @SuppressWarnings("unchecked")
5504         public <T> T[] toArray(T[] a) {
5505             final int n = this.n;
5506             if (a.length < n) {
5507                 a = (T[])java.lang.reflect.Array
5508                     .newInstance(a.getClass().getComponentType(), n);
5509                 if (element != null)
5510                     Arrays.fill(a, 0, n, element);
5511             } else {
5512                 Arrays.fill(a, 0, n, element);
5513                 if (a.length > n)
5514                     a[n] = null;
5515             }
5516             return a;
5517         }
5518 
5519         public List<E> subList(int fromIndex, int toIndex) {
5520             if (fromIndex < 0)
5521                 throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
5522             if (toIndex > n)
5523                 throw new IndexOutOfBoundsException("toIndex = " + toIndex);
5524             if (fromIndex > toIndex)
5525                 throw new IllegalArgumentException("fromIndex(" + fromIndex +
5526                                                    ") > toIndex(" + toIndex + ")");
5527             return new CopiesList<>(toIndex - fromIndex, element);
5528         }
5529 
5530         @Override
5531         public int hashCode() {
5532             if (n == 0) return 1;
5533             // hashCode of n repeating elements is 31^n + elementHash * Sum(31^k, k = 0..n-1)
5534             // this implementation completes in O(log(n)) steps taking advantage of
5535             // 31^(2*n) = (31^n)^2 and Sum(31^k, k = 0..(2*n-1)) = Sum(31^k, k = 0..n-1) * (31^n + 1)
5536             int pow = 31;
5537             int sum = 1;
5538             for (int i = Integer.numberOfLeadingZeros(n) + 1; i < Integer.SIZE; i++) {
5539                 sum *= pow + 1;
5540                 pow *= pow;
5541                 if ((n << i) < 0) {
5542                     pow *= 31;
5543                     sum = sum * 31 + 1;
5544                 }
5545             }
5546             return pow + sum * (element == null ? 0 : element.hashCode());
5547         }
5548 
5549         @Override
5550         public boolean equals(Object o) {
5551             if (o == this)
5552                 return true;
5553             // Android-changed: (b/247094511) instanceof pattern variable is not yet supported.
5554             // if (o instanceof CopiesList<?> other) {
5555             if (o instanceof CopiesList<?>) {
5556                 CopiesList<?> other = (CopiesList<?>) o;
5557                 return n == other.n && (n == 0 || eq(element, other.element));
5558             }
5559             if (!(o instanceof List))
5560                 return false;
5561 
5562             int remaining = n;
5563             E e = element;
5564             Iterator<?> itr = ((List<?>) o).iterator();
5565             if (e == null) {
5566                 while (itr.hasNext() && remaining-- > 0) {
5567                     if (itr.next() != null)
5568                         return false;
5569                 }
5570             } else {
5571                 while (itr.hasNext() && remaining-- > 0) {
5572                     if (!e.equals(itr.next()))
5573                         return false;
5574                 }
5575             }
5576             return remaining == 0 && !itr.hasNext();
5577         }
5578 
5579         // Override default methods in Collection
5580         @Override
5581         public Stream<E> stream() {
5582             return IntStream.range(0, n).mapToObj(i -> element);
5583         }
5584 
5585         @Override
5586         public Stream<E> parallelStream() {
5587             return IntStream.range(0, n).parallel().mapToObj(i -> element);
5588         }
5589 
5590         @Override
5591         public Spliterator<E> spliterator() {
5592             return stream().spliterator();
5593         }
5594 
5595         @java.io.Serial
5596         private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
5597             ois.defaultReadObject();
5598             SharedSecrets.getJavaObjectInputStreamAccess().checkArray(ois, Object[].class, n);
5599         }
5600     }
5601 
5602     /**
5603      * Returns a comparator that imposes the reverse of the <em>natural
5604      * ordering</em> on a collection of objects that implement the
5605      * {@code Comparable} interface.  (The natural ordering is the ordering
5606      * imposed by the objects' own {@code compareTo} method.)  This enables a
5607      * simple idiom for sorting (or maintaining) collections (or arrays) of
5608      * objects that implement the {@code Comparable} interface in
5609      * reverse-natural-order.  For example, suppose {@code a} is an array of
5610      * strings. Then: <pre>
5611      *          Arrays.sort(a, Collections.reverseOrder());
5612      * </pre> sorts the array in reverse-lexicographic (alphabetical) order.<p>
5613      *
5614      * The returned comparator is serializable.
5615      *
5616      * @apiNote
5617      * This method returns a {@code Comparator} that is suitable for sorting
5618      * elements in reverse order. To obtain a reverse-ordered <i>view</i> of a
5619      * sequenced collection, use the {@link SequencedCollection#reversed
5620      * SequencedCollection.reversed} method. Or, to obtain a reverse-ordered
5621      * <i>view</i> of a sequenced map, use the {@link SequencedMap#reversed
5622      * SequencedMap.reversed} method.
5623      *
5624      * @param  <T> the class of the objects compared by the comparator
5625      * @return A comparator that imposes the reverse of the <i>natural
5626      *         ordering</i> on a collection of objects that implement
5627      *         the {@code Comparable} interface.
5628      * @see Comparable
5629      */
5630     @SuppressWarnings("unchecked")
5631     public static <T> Comparator<T> reverseOrder() {
5632         return (Comparator<T>) ReverseComparator.REVERSE_ORDER;
5633     }
5634 
5635     /**
5636      * @serial include
5637      */
5638     private static class ReverseComparator
5639         implements Comparator<Comparable<Object>>, Serializable {
5640 
5641         @java.io.Serial
5642         private static final long serialVersionUID = 7207038068494060240L;
5643 
5644         static final ReverseComparator REVERSE_ORDER
5645             = new ReverseComparator();
5646 
5647         public int compare(Comparable<Object> c1, Comparable<Object> c2) {
5648             return c2.compareTo(c1);
5649         }
5650 
5651         @java.io.Serial
5652         private Object readResolve() { return Collections.reverseOrder(); }
5653 
5654         @Override
5655         public Comparator<Comparable<Object>> reversed() {
5656             return Comparator.naturalOrder();
5657         }
5658     }
5659 
5660     /**
5661      * Returns a comparator that imposes the reverse ordering of the specified
5662      * comparator.  If the specified comparator is {@code null}, this method is
5663      * equivalent to {@link #reverseOrder()} (in other words, it returns a
5664      * comparator that imposes the reverse of the <em>natural ordering</em> on
5665      * a collection of objects that implement the Comparable interface).
5666      *
5667      * <p>The returned comparator is serializable (assuming the specified
5668      * comparator is also serializable or {@code null}).
5669      *
5670      * @apiNote
5671      * This method returns a {@code Comparator} that is suitable for sorting
5672      * elements in reverse order. To obtain a reverse-ordered <i>view</i> of a
5673      * sequenced collection, use the {@link SequencedCollection#reversed
5674      * SequencedCollection.reversed} method. Or, to obtain a reverse-ordered
5675      * <i>view</i> of a sequenced map, use the {@link SequencedMap#reversed
5676      * SequencedMap.reversed} method.
5677      *
5678      * @param <T> the class of the objects compared by the comparator
5679      * @param cmp a comparator who's ordering is to be reversed by the returned
5680      * comparator or {@code null}
5681      * @return A comparator that imposes the reverse ordering of the
5682      *         specified comparator.
5683      * @since 1.5
5684      */
5685     @SuppressWarnings("unchecked")
5686     public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) {
5687         if (cmp == null) {
5688             return (Comparator<T>) ReverseComparator.REVERSE_ORDER;
5689         } else if (cmp == ReverseComparator.REVERSE_ORDER) {
5690             return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
5691         } else if (cmp == Comparators.NaturalOrderComparator.INSTANCE) {
5692             return (Comparator<T>) ReverseComparator.REVERSE_ORDER;
5693         } else if (cmp instanceof ReverseComparator2) {
5694             return ((ReverseComparator2<T>) cmp).cmp;
5695         } else {
5696             return new ReverseComparator2<>(cmp);
5697         }
5698     }
5699 
5700     /**
5701      * @serial include
5702      */
5703     private static class ReverseComparator2<T> implements Comparator<T>,
5704         Serializable
5705     {
5706         @java.io.Serial
5707         private static final long serialVersionUID = 4374092139857L;
5708 
5709         /**
5710          * The comparator specified in the static factory.  This will never
5711          * be null, as the static factory returns a ReverseComparator
5712          * instance if its argument is null.
5713          *
5714          * @serial
5715          */
5716         @SuppressWarnings("serial") // Conditionally serializable
5717         final Comparator<T> cmp;
5718 
5719         ReverseComparator2(Comparator<T> cmp) {
5720             assert cmp != null;
5721             this.cmp = cmp;
5722         }
5723 
5724         public int compare(T t1, T t2) {
5725             return cmp.compare(t2, t1);
5726         }
5727 
5728         public boolean equals(Object o) {
5729             return (o == this) ||
5730                 (o instanceof ReverseComparator2<?> that &&
5731                  cmp.equals(that.cmp));
5732         }
5733 
5734         public int hashCode() {
5735             return cmp.hashCode() ^ Integer.MIN_VALUE;
5736         }
5737 
5738         @Override
5739         public Comparator<T> reversed() {
5740             return cmp;
5741         }
5742     }
5743 
5744     /**
5745      * Returns an enumeration over the specified collection.  This provides
5746      * interoperability with legacy APIs that require an enumeration
5747      * as input.
5748      *
5749      * <p>The iterator returned from a call to {@link Enumeration#asIterator()}
5750      * does not support removal of elements from the specified collection.  This
5751      * is necessary to avoid unintentionally increasing the capabilities of the
5752      * returned enumeration.
5753      *
5754      * @param  <T> the class of the objects in the collection
5755      * @param c the collection for which an enumeration is to be returned.
5756      * @return an enumeration over the specified collection.
5757      * @see Enumeration
5758      */
5759     public static <T> Enumeration<T> enumeration(final Collection<T> c) {
5760         return new Enumeration<>() {
5761             private final Iterator<T> i = c.iterator();
5762 
5763             public boolean hasMoreElements() {
5764                 return i.hasNext();
5765             }
5766 
5767             public T nextElement() {
5768                 return i.next();
5769             }
5770         };
5771     }
5772 
5773     /**
5774      * Returns an array list containing the elements returned by the
5775      * specified enumeration in the order they are returned by the
5776      * enumeration.  This method provides interoperability between
5777      * legacy APIs that return enumerations and new APIs that require
5778      * collections.
5779      *
5780      * @param <T> the class of the objects returned by the enumeration
5781      * @param e enumeration providing elements for the returned
5782      *          array list
5783      * @return an array list containing the elements returned
5784      *         by the specified enumeration.
5785      * @since 1.4
5786      * @see Enumeration
5787      * @see ArrayList
5788      */
5789     public static <T> ArrayList<T> list(Enumeration<T> e) {
5790         ArrayList<T> l = new ArrayList<>();
5791         while (e.hasMoreElements())
5792             l.add(e.nextElement());
5793         return l;
5794     }
5795 
5796     /**
5797      * Returns true if the specified arguments are equal, or both null.
5798      *
5799      * NB: Do not replace with Object.equals until JDK-8015417 is resolved.
5800      */
5801     static boolean eq(Object o1, Object o2) {
5802         return o1==null ? o2==null : o1.equals(o2);
5803     }
5804 
5805     /**
5806      * Returns the number of elements in the specified collection equal to the
5807      * specified object.  More formally, returns the number of elements
5808      * {@code e} in the collection such that
5809      * {@code Objects.equals(o, e)}.
5810      *
5811      * @param c the collection in which to determine the frequency
5812      *     of {@code o}
5813      * @param o the object whose frequency is to be determined
5814      * @return the number of elements in {@code c} equal to {@code o}
5815      * @throws NullPointerException if {@code c} is null
5816      * @since 1.5
5817      */
5818     public static int frequency(Collection<?> c, Object o) {
5819         int result = 0;
5820         if (o == null) {
5821             for (Object e : c)
5822                 if (e == null)
5823                     result++;
5824         } else {
5825             for (Object e : c)
5826                 if (o.equals(e))
5827                     result++;
5828         }
5829         return result;
5830     }
5831 
5832     /**
5833      * Returns {@code true} if the two specified collections have no
5834      * elements in common.
5835      *
5836      * <p>Care must be exercised if this method is used on collections that
5837      * do not comply with the general contract for {@code Collection}.
5838      * Implementations may elect to iterate over either collection and test
5839      * for containment in the other collection (or to perform any equivalent
5840      * computation).  If either collection uses a nonstandard equality test
5841      * (as does a {@link SortedSet} whose ordering is not <em>compatible with
5842      * equals</em>, or the key set of an {@link IdentityHashMap}), both
5843      * collections must use the same nonstandard equality test, or the
5844      * result of this method is undefined.
5845      *
5846      * <p>Care must also be exercised when using collections that have
5847      * restrictions on the elements that they may contain. Collection
5848      * implementations are allowed to throw exceptions for any operation
5849      * involving elements they deem ineligible. For absolute safety the
5850      * specified collections should contain only elements which are
5851      * eligible elements for both collections.
5852      *
5853      * <p>Note that it is permissible to pass the same collection in both
5854      * parameters, in which case the method will return {@code true} if and
5855      * only if the collection is empty.
5856      *
5857      * @param c1 a collection
5858      * @param c2 a collection
5859      * @return {@code true} if the two specified collections have no
5860      * elements in common.
5861      * @throws NullPointerException if either collection is {@code null}.
5862      * @throws NullPointerException if one collection contains a {@code null}
5863      * element and {@code null} is not an eligible element for the other collection.
5864      * (<a href="Collection.html#optional-restrictions">optional</a>)
5865      * @throws ClassCastException if one collection contains an element that is
5866      * of a type which is ineligible for the other collection.
5867      * (<a href="Collection.html#optional-restrictions">optional</a>)
5868      * @since 1.5
5869      */
5870     public static boolean disjoint(Collection<?> c1, Collection<?> c2) {
5871         // The collection to be used for contains(). Preference is given to
5872         // the collection who's contains() has lower O() complexity.
5873         Collection<?> contains = c2;
5874         // The collection to be iterated. If the collections' contains() impl
5875         // are of different O() complexity, the collection with slower
5876         // contains() will be used for iteration. For collections who's
5877         // contains() are of the same complexity then best performance is
5878         // achieved by iterating the smaller collection.
5879         Collection<?> iterate = c1;
5880 
5881         // Performance optimization cases. The heuristics:
5882         //   1. Generally iterate over c1.
5883         //   2. If c1 is a Set then iterate over c2.
5884         //   3. If either collection is empty then result is always true.
5885         //   4. Iterate over the smaller Collection.
5886         if (c1 instanceof Set) {
5887             // Use c1 for contains as a Set's contains() is expected to perform
5888             // better than O(N/2)
5889             iterate = c2;
5890             contains = c1;
5891         } else if (!(c2 instanceof Set)) {
5892             // Both are mere Collections. Iterate over smaller collection.
5893             // Example: If c1 contains 3 elements and c2 contains 50 elements and
5894             // assuming contains() requires ceiling(N/2) comparisons then
5895             // checking for all c1 elements in c2 would require 75 comparisons
5896             // (3 * ceiling(50/2)) vs. checking all c2 elements in c1 requiring
5897             // 100 comparisons (50 * ceiling(3/2)).
5898             int c1size = c1.size();
5899             int c2size = c2.size();
5900             if (c1size == 0 || c2size == 0) {
5901                 // At least one collection is empty. Nothing will match.
5902                 return true;
5903             }
5904 
5905             if (c1size > c2size) {
5906                 iterate = c2;
5907                 contains = c1;
5908             }
5909         }
5910 
5911         for (Object e : iterate) {
5912             if (contains.contains(e)) {
5913                // Found a common element. Collections are not disjoint.
5914                 return false;
5915             }
5916         }
5917 
5918         // No common elements were found.
5919         return true;
5920     }
5921 
5922     /**
5923      * Adds all of the specified elements to the specified collection.
5924      * Elements to be added may be specified individually or as an array.
5925      * The behaviour of this convenience method is similar to that of
5926      * {@code c.addAll(Collections.unmodifiableList(Arrays.asList(elements)))}.
5927      *
5928      * <p>When elements are specified individually, this method provides a
5929      * convenient way to add a few elements to an existing collection:
5930      * <pre>
5931      *     Collections.addAll(flavors, "Peaches 'n Plutonium", "Rocky Racoon");
5932      * </pre>
5933      *
5934      * @param  <T> the class of the elements to add and of the collection
5935      * @param c the collection into which {@code elements} are to be inserted
5936      * @param elements the elements to insert into {@code c}
5937      * @return {@code true} if the collection changed as a result of the call
5938      * @throws UnsupportedOperationException if {@code c} does not support
5939      *         the {@code add} operation
5940      * @throws NullPointerException if {@code elements} contains one or more
5941      *         null values and {@code c} does not permit null elements, or
5942      *         if {@code c} or {@code elements} are {@code null}
5943      * @throws IllegalArgumentException if some property of a value in
5944      *         {@code elements} prevents it from being added to {@code c}
5945      * @see Collection#addAll(Collection)
5946      * @since 1.5
5947      */
5948     @SafeVarargs
5949     public static <T> boolean addAll(Collection<? super T> c, T... elements) {
5950         boolean result = false;
5951         for (T element : elements)
5952             result |= c.add(element);
5953         return result;
5954     }
5955 
5956     /**
5957      * Returns a set backed by the specified map.  The resulting set displays
5958      * the same ordering, concurrency, and performance characteristics as the
5959      * backing map.  In essence, this factory method provides a {@link Set}
5960      * implementation corresponding to any {@link Map} implementation.  There
5961      * is no need to use this method on a {@link Map} implementation that
5962      * already has a corresponding {@link Set} implementation (such as {@link
5963      * HashMap} or {@link TreeMap}).
5964      *
5965      * <p>Each method invocation on the set returned by this method results in
5966      * exactly one method invocation on the backing map or its {@code keySet}
5967      * view, with one exception.  The {@code addAll} method is implemented
5968      * as a sequence of {@code put} invocations on the backing map.
5969      *
5970      * <p>The specified map must be empty at the time this method is invoked,
5971      * and should not be accessed directly after this method returns.  These
5972      * conditions are ensured if the map is created empty, passed directly
5973      * to this method, and no reference to the map is retained, as illustrated
5974      * in the following code fragment:
5975      * <pre>
5976      *    Set&lt;Object&gt; weakHashSet = Collections.newSetFromMap(
5977      *        new WeakHashMap&lt;Object, Boolean&gt;());
5978      * </pre>
5979      *
5980      * @param <E> the class of the map keys and of the objects in the
5981      *        returned set
5982      * @param map the backing map
5983      * @return the set backed by the map
5984      * @throws IllegalArgumentException if {@code map} is not empty
5985      * @since 1.6
5986      */
5987     public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) {
5988         if (! map.isEmpty()) // implicit null check
5989             throw new IllegalArgumentException("Map is non-empty");
5990         return new SetFromMap<>(map);
5991     }
5992 
5993     /**
5994      * @serial include
5995      */
5996     private static class SetFromMap<E> extends AbstractSet<E>
5997         implements Set<E>, Serializable
5998     {
5999         @SuppressWarnings("serial") // Conditionally serializable
6000         final Map<E, Boolean> m;          // The backing map
6001         private transient Set<E> s;       // Its keySet
6002 
6003         SetFromMap(Map<E, Boolean> map) {
6004             m = map;
6005             s = map.keySet();
6006         }
6007 
6008         public void clear()               {        m.clear(); }
6009         public int size()                 { return m.size(); }
6010         public boolean isEmpty()          { return m.isEmpty(); }
6011         public boolean contains(Object o) { return m.containsKey(o); }
6012         public boolean remove(Object o)   { return m.remove(o) != null; }
6013         public boolean add(E e) { return m.put(e, Boolean.TRUE) == null; }
6014         public Iterator<E> iterator()     { return s.iterator(); }
6015         public Object[] toArray()         { return s.toArray(); }
6016         public <T> T[] toArray(T[] a)     { return s.toArray(a); }
6017         public String toString()          { return s.toString(); }
6018         public int hashCode()             { return s.hashCode(); }
6019         public boolean equals(Object o)   { return o == this || s.equals(o); }
6020         public boolean containsAll(Collection<?> c) {return s.containsAll(c);}
6021         public boolean removeAll(Collection<?> c)   {return s.removeAll(c);}
6022         public boolean retainAll(Collection<?> c)   {return s.retainAll(c);}
6023         // addAll is the only inherited implementation
6024 
6025         // Override default methods in Collection
6026         @Override
6027         public void forEach(Consumer<? super E> action) {
6028             s.forEach(action);
6029         }
6030         @Override
6031         public boolean removeIf(Predicate<? super E> filter) {
6032             return s.removeIf(filter);
6033         }
6034 
6035         @Override
6036         public Spliterator<E> spliterator() {return s.spliterator();}
6037         @Override
6038         public Stream<E> stream()           {return s.stream();}
6039         @Override
6040         public Stream<E> parallelStream()   {return s.parallelStream();}
6041 
6042         @java.io.Serial
6043         private static final long serialVersionUID = 2454657854757543876L;
6044 
6045         @java.io.Serial
6046         private void readObject(java.io.ObjectInputStream stream)
6047             throws IOException, ClassNotFoundException
6048         {
6049             stream.defaultReadObject();
6050             s = m.keySet();
6051         }
6052 
6053         @java.io.Serial
6054         private void readObjectNoData() throws java.io.ObjectStreamException {
6055             throw new java.io.InvalidObjectException("missing SetFromMap data");
6056         }
6057     }
6058 
6059     /**
6060      * Returns a sequenced set backed by the specified map.  The resulting set displays
6061      * the same ordering, concurrency, and performance characteristics as the
6062      * backing map. In essence, this factory method provides a {@link SequencedSet}
6063      * implementation corresponding to any {@link SequencedMap} implementation.
6064      *
6065      * <p>Each method invocation on the set returned by this method results in
6066      * exactly one method invocation on the backing map or its {@code keySet}
6067      * view, with one exception.  The {@code addAll} method is implemented
6068      * as a sequence of {@code put} invocations on the backing map.
6069      *
6070      * <p>The specified map must be empty at the time this method is invoked,
6071      * and should not be accessed directly after this method returns.  These
6072      * conditions are ensured if the map is created empty, passed directly
6073      * to this method, and no reference to the map is retained.
6074      *
6075      * @apiNote
6076      * The following example code creates a {@code SequencedSet} from a
6077      * {@code LinkedHashMap}. This differs from a {@code LinkedHashSet}
6078      * in that the map's {@code removeEldestEntry} is overridden to provide
6079      * an eviction policy, which is not possible with a {@code LinkedHashSet}.
6080      *
6081      * {@snippet :
6082      *     SequencedSet<String> set = Collections.newSequencedSetFromMap(
6083      *         new LinkedHashMap<String, Boolean>() {
6084      *             protected boolean removeEldestEntry(Map.Entry<String, Boolean> e) {
6085      *                 return this.size() > 5;
6086      *             }
6087      *        });
6088      * }
6089      *
6090      * @param <E> the class of the map keys and of the objects in the
6091      *        returned set
6092      * @param map the backing map
6093      * @return the set backed by the map
6094      * @throws IllegalArgumentException if {@code map} is not empty
6095      * @since 21
6096      */
6097     public static <E> SequencedSet<E> newSequencedSetFromMap(SequencedMap<E, Boolean> map) {
6098         if (! map.isEmpty()) // implicit null check
6099             throw new IllegalArgumentException("Map is non-empty");
6100         return new SequencedSetFromMap<>(map);
6101     }
6102 
6103     /**
6104      * @serial include
6105      */
6106     private static class SequencedSetFromMap<E> extends SetFromMap<E> implements SequencedSet<E> {
6107         private E nsee(Map.Entry<E, Boolean> e) {
6108             if (e == null) {
6109                 throw new NoSuchElementException();
6110             } else {
6111                 return e.getKey();
6112             }
6113         }
6114 
6115         private SequencedMap<E, Boolean> map() {
6116             return (SequencedMap<E, Boolean>) super.m;
6117         }
6118 
6119         SequencedSetFromMap(SequencedMap<E, Boolean> map) {
6120             super(map);
6121         }
6122 
6123         // Even though this wrapper class is serializable, the reversed view is effectively
6124         // not serializable because it points to the reversed map view, which usually isn't
6125         // serializable.
6126         public SequencedSet<E> reversed() { return new SequencedSetFromMap<>(map().reversed()); }
6127 
6128         public void addFirst(E e) { map().putFirst(e, Boolean.TRUE); }
6129         public void addLast(E e)  { map().putLast(e, Boolean.TRUE); }
6130         public E getFirst()       { return nsee(map().firstEntry()); }
6131         public E getLast()        { return nsee(map().lastEntry()); }
6132         public E removeFirst()    { return nsee(map().pollFirstEntry()); }
6133         public E removeLast()     { return nsee(map().pollLastEntry()); }
6134 
6135         @java.io.Serial
6136         private static final long serialVersionUID = -3943479744841433802L;
6137     }
6138 
6139     /**
6140      * Returns a view of a {@link Deque} as a Last-in-first-out (Lifo)
6141      * {@link Queue}. Method {@code add} is mapped to {@code push},
6142      * {@code remove} is mapped to {@code pop} and so on. This
6143      * view can be useful when you would like to use a method
6144      * requiring a {@code Queue} but you need Lifo ordering.
6145      *
6146      * <p>Each method invocation on the queue returned by this method
6147      * results in exactly one method invocation on the backing deque, with
6148      * one exception.  The {@link Queue#addAll addAll} method is
6149      * implemented as a sequence of {@link Deque#addFirst addFirst}
6150      * invocations on the backing deque.
6151      *
6152      * @apiNote
6153      * This method provides a view that inverts the sense of certain operations,
6154      * but it doesn't reverse the encounter order. To obtain a reverse-ordered
6155      * view, use the {@link Deque#reversed Deque.reversed} method.
6156      *
6157      * @param  <T> the class of the objects in the deque
6158      * @param deque the deque
6159      * @return the queue
6160      * @since  1.6
6161      */
6162     public static <T> Queue<T> asLifoQueue(Deque<T> deque) {
6163         return new AsLIFOQueue<>(Objects.requireNonNull(deque));
6164     }
6165 
6166     /**
6167      * @serial include
6168      */
6169     static class AsLIFOQueue<E> extends AbstractQueue<E>
6170         implements Queue<E>, Serializable {
6171         @java.io.Serial
6172         private static final long serialVersionUID = 1802017725587941708L;
6173         @SuppressWarnings("serial") // Conditionally serializable
6174         private final Deque<E> q;
6175         AsLIFOQueue(Deque<E> q)                     { this.q = q; }
6176         public boolean add(E e)                     { q.addFirst(e); return true; }
6177         public boolean offer(E e)                   { return q.offerFirst(e); }
6178         public E poll()                             { return q.pollFirst(); }
6179         public E remove()                           { return q.removeFirst(); }
6180         public E peek()                             { return q.peekFirst(); }
6181         public E element()                          { return q.getFirst(); }
6182         public void clear()                         {        q.clear(); }
6183         public int size()                           { return q.size(); }
6184         public boolean isEmpty()                    { return q.isEmpty(); }
6185         public boolean contains(Object o)           { return q.contains(o); }
6186         public boolean remove(Object o)             { return q.remove(o); }
6187         public Iterator<E> iterator()               { return q.iterator(); }
6188         public Object[] toArray()                   { return q.toArray(); }
6189         public <T> T[] toArray(T[] a)               { return q.toArray(a); }
6190         public <T> T[] toArray(IntFunction<T[]> f)  { return q.toArray(f); }
6191         public String toString()                    { return q.toString(); }
6192         public boolean containsAll(Collection<?> c) { return q.containsAll(c); }
6193         public boolean removeAll(Collection<?> c)   { return q.removeAll(c); }
6194         public boolean retainAll(Collection<?> c)   { return q.retainAll(c); }
6195         // We use inherited addAll; forwarding addAll would be wrong
6196 
6197         // Override default methods in Collection
6198         @Override
6199         public void forEach(Consumer<? super E> action) {q.forEach(action);}
6200         @Override
6201         public boolean removeIf(Predicate<? super E> filter) {
6202             return q.removeIf(filter);
6203         }
6204         @Override
6205         public Spliterator<E> spliterator() {return q.spliterator();}
6206         @Override
6207         public Stream<E> stream()           {return q.stream();}
6208         @Override
6209         public Stream<E> parallelStream()   {return q.parallelStream();}
6210     }
6211 }
6212