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 >= 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 >= 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 < 0 || i >= list.size() 561 * || j < 0 || j >= 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<String> 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<String> 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<String, Date> 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<Object> weakHashSet = Collections.newSetFromMap( 5977 * new WeakHashMap<Object, Boolean>()); 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