1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package java.util; 19 20import java.io.IOException; 21import java.io.ObjectInputStream; 22import java.io.ObjectOutputStream; 23import java.io.ObjectStreamException; 24import java.io.Serializable; 25import java.lang.reflect.Array; 26 27/** 28 * {@code Collections} contains static methods which operate on 29 * {@code Collection} classes. 30 * 31 * @since 1.2 32 */ 33public class Collections { 34 35 private static final Iterator<?> EMPTY_ITERATOR = new Iterator<Object>() { 36 @Override public boolean hasNext() { 37 return false; 38 } 39 40 @Override public Object next() { 41 throw new NoSuchElementException(); 42 } 43 44 @Override public void remove() { 45 throw new IllegalStateException(); 46 } 47 }; 48 49 private static final Enumeration<?> EMPTY_ENUMERATION = new Enumeration<Object>() { 50 @Override public boolean hasMoreElements() { 51 return false; 52 } 53 54 @Override public Object nextElement() { 55 throw new NoSuchElementException(); 56 } 57 }; 58 59 private static final class CopiesList<E> extends AbstractList<E> implements Serializable { 60 private static final long serialVersionUID = 2739099268398711800L; 61 private final int n; 62 private final E element; 63 64 CopiesList(int length, E object) { 65 if (length < 0) { 66 throw new IllegalArgumentException("length < 0: " + length); 67 } 68 n = length; 69 element = object; 70 } 71 72 @Override public boolean contains(Object object) { 73 return element == null ? object == null : element.equals(object); 74 } 75 76 @Override public int size() { 77 return n; 78 } 79 80 @Override public E get(int location) { 81 if (location >= 0 && location < n) { 82 return element; 83 } 84 throw new IndexOutOfBoundsException(); 85 } 86 } 87 88 @SuppressWarnings("unchecked") 89 private static final class EmptyList extends AbstractList 90 implements RandomAccess, Serializable { 91 private static final long serialVersionUID = 8842843931221139166L; 92 93 @Override public boolean contains(Object object) { 94 return false; 95 } 96 97 @Override public int size() { 98 return 0; 99 } 100 101 @Override public Object get(int location) { 102 throw new IndexOutOfBoundsException(); 103 } 104 105 private Object readResolve() { 106 return Collections.EMPTY_LIST; 107 } 108 } 109 110 @SuppressWarnings("unchecked") 111 private static final class EmptySet extends AbstractSet implements Serializable { 112 private static final long serialVersionUID = 1582296315990362920L; 113 114 @Override public boolean contains(Object object) { 115 return false; 116 } 117 118 @Override public int size() { 119 return 0; 120 } 121 122 @Override public Iterator iterator() { 123 return EMPTY_ITERATOR; 124 } 125 126 private Object readResolve() { 127 return Collections.EMPTY_SET; 128 } 129 } 130 131 @SuppressWarnings("unchecked") 132 private static final class EmptyMap extends AbstractMap implements Serializable { 133 private static final long serialVersionUID = 6428348081105594320L; 134 135 @Override public boolean containsKey(Object key) { 136 return false; 137 } 138 139 @Override public boolean containsValue(Object value) { 140 return false; 141 } 142 143 @Override public Set entrySet() { 144 return EMPTY_SET; 145 } 146 147 @Override public Object get(Object key) { 148 return null; 149 } 150 151 @Override public Set keySet() { 152 return EMPTY_SET; 153 } 154 155 @Override public Collection values() { 156 return EMPTY_LIST; 157 } 158 159 private Object readResolve() { 160 return Collections.EMPTY_MAP; 161 } 162 } 163 164 /** 165 * An empty immutable instance of {@link List}. 166 */ 167 @SuppressWarnings("unchecked") 168 public static final List EMPTY_LIST = new EmptyList(); 169 170 /** 171 * An empty immutable instance of {@link Set}. 172 */ 173 @SuppressWarnings("unchecked") 174 public static final Set EMPTY_SET = new EmptySet(); 175 176 /** 177 * An empty immutable instance of {@link Map}. 178 */ 179 @SuppressWarnings("unchecked") 180 public static final Map EMPTY_MAP = new EmptyMap(); 181 182 /** 183 * This class is a singleton so that equals() and hashCode() work properly. 184 */ 185 private static final class ReverseComparator<T> implements Comparator<T>, Serializable { 186 private static final ReverseComparator<Object> INSTANCE = new ReverseComparator<Object>(); 187 188 private static final long serialVersionUID = 7207038068494060240L; 189 190 @SuppressWarnings("unchecked") 191 @Override public int compare(T o1, T o2) { 192 Comparable<T> c2 = (Comparable<T>) o2; 193 return c2.compareTo(o1); 194 } 195 196 private Object readResolve() throws ObjectStreamException { 197 return INSTANCE; 198 } 199 } 200 201 private static final class ReverseComparator2<T> implements Comparator<T>, Serializable { 202 private static final long serialVersionUID = 4374092139857L; 203 private final Comparator<T> cmp; 204 205 ReverseComparator2(Comparator<T> comparator) { 206 this.cmp = comparator; 207 } 208 209 @Override public int compare(T o1, T o2) { 210 return cmp.compare(o2, o1); 211 } 212 213 @Override public boolean equals(Object o) { 214 return o instanceof ReverseComparator2 215 && ((ReverseComparator2) o).cmp.equals(cmp); 216 } 217 218 @Override public int hashCode() { 219 return ~cmp.hashCode(); 220 } 221 } 222 223 private static final class SingletonSet<E> extends AbstractSet<E> implements Serializable { 224 private static final long serialVersionUID = 3193687207550431679L; 225 final E element; 226 227 SingletonSet(E object) { 228 element = object; 229 } 230 231 @Override public boolean contains(Object object) { 232 return element == null ? object == null : element.equals(object); 233 } 234 235 @Override public int size() { 236 return 1; 237 } 238 239 @Override public Iterator<E> iterator() { 240 return new Iterator<E>() { 241 boolean hasNext = true; 242 243 @Override public boolean hasNext() { 244 return hasNext; 245 } 246 247 @Override public E next() { 248 if (hasNext) { 249 hasNext = false; 250 return element; 251 } 252 throw new NoSuchElementException(); 253 } 254 255 @Override public void remove() { 256 throw new UnsupportedOperationException(); 257 } 258 }; 259 } 260 } 261 262 private static final class SingletonList<E> extends AbstractList<E> implements Serializable { 263 private static final long serialVersionUID = 3093736618740652951L; 264 265 final E element; 266 267 SingletonList(E object) { 268 element = object; 269 } 270 271 @Override public boolean contains(Object object) { 272 return element == null ? object == null : element.equals(object); 273 } 274 275 @Override public E get(int location) { 276 if (location == 0) { 277 return element; 278 } 279 throw new IndexOutOfBoundsException(); 280 } 281 282 @Override public int size() { 283 return 1; 284 } 285 } 286 287 private static final class SingletonMap<K, V> extends AbstractMap<K, V> 288 implements Serializable { 289 private static final long serialVersionUID = -6979724477215052911L; 290 291 final K k; 292 final V v; 293 294 SingletonMap(K key, V value) { 295 k = key; 296 v = value; 297 } 298 299 @Override public boolean containsKey(Object key) { 300 return k == null ? key == null : k.equals(key); 301 } 302 303 @Override public boolean containsValue(Object value) { 304 return v == null ? value == null : v.equals(value); 305 } 306 307 @Override public V get(Object key) { 308 if (containsKey(key)) { 309 return v; 310 } 311 return null; 312 } 313 314 @Override public int size() { 315 return 1; 316 } 317 318 @Override public Set<Map.Entry<K, V>> entrySet() { 319 return new AbstractSet<Map.Entry<K, V>>() { 320 @Override public boolean contains(Object object) { 321 if (object instanceof Map.Entry) { 322 Map.Entry<?, ?> entry = (Map.Entry<?, ?>) object; 323 return containsKey(entry.getKey()) 324 && containsValue(entry.getValue()); 325 } 326 return false; 327 } 328 329 @Override public int size() { 330 return 1; 331 } 332 333 @Override public Iterator<Map.Entry<K, V>> iterator() { 334 return new Iterator<Map.Entry<K, V>>() { 335 boolean hasNext = true; 336 337 @Override public boolean hasNext() { 338 return hasNext; 339 } 340 341 @Override public Map.Entry<K, V> next() { 342 if (!hasNext) { 343 throw new NoSuchElementException(); 344 } 345 346 hasNext = false; 347 return new MapEntry<K, V>(k, v) { 348 @Override public V setValue(V value) { 349 throw new UnsupportedOperationException(); 350 } 351 }; 352 } 353 354 @Override public void remove() { 355 throw new UnsupportedOperationException(); 356 } 357 }; 358 } 359 }; 360 } 361 } 362 363 static class SynchronizedCollection<E> implements Collection<E>, Serializable { 364 private static final long serialVersionUID = 3053995032091335093L; 365 final Collection<E> c; 366 final Object mutex; 367 368 SynchronizedCollection(Collection<E> collection) { 369 c = collection; 370 mutex = this; 371 } 372 373 SynchronizedCollection(Collection<E> collection, Object mutex) { 374 c = collection; 375 this.mutex = mutex; 376 } 377 378 @Override public boolean add(E object) { 379 synchronized (mutex) { 380 return c.add(object); 381 } 382 } 383 384 @Override public boolean addAll(Collection<? extends E> collection) { 385 synchronized (mutex) { 386 return c.addAll(collection); 387 } 388 } 389 390 @Override public void clear() { 391 synchronized (mutex) { 392 c.clear(); 393 } 394 } 395 396 @Override public boolean contains(Object object) { 397 synchronized (mutex) { 398 return c.contains(object); 399 } 400 } 401 402 @Override public boolean containsAll(Collection<?> collection) { 403 synchronized (mutex) { 404 return c.containsAll(collection); 405 } 406 } 407 408 @Override public boolean isEmpty() { 409 synchronized (mutex) { 410 return c.isEmpty(); 411 } 412 } 413 414 @Override public Iterator<E> iterator() { 415 synchronized (mutex) { 416 return c.iterator(); 417 } 418 } 419 420 @Override public boolean remove(Object object) { 421 synchronized (mutex) { 422 return c.remove(object); 423 } 424 } 425 426 @Override public boolean removeAll(Collection<?> collection) { 427 synchronized (mutex) { 428 return c.removeAll(collection); 429 } 430 } 431 432 @Override public boolean retainAll(Collection<?> collection) { 433 synchronized (mutex) { 434 return c.retainAll(collection); 435 } 436 } 437 438 @Override public int size() { 439 synchronized (mutex) { 440 return c.size(); 441 } 442 } 443 444 @Override public java.lang.Object[] toArray() { 445 synchronized (mutex) { 446 return c.toArray(); 447 } 448 } 449 450 @Override public String toString() { 451 synchronized (mutex) { 452 return c.toString(); 453 } 454 } 455 456 @Override public <T> T[] toArray(T[] array) { 457 synchronized (mutex) { 458 return c.toArray(array); 459 } 460 } 461 462 private void writeObject(ObjectOutputStream stream) throws IOException { 463 synchronized (mutex) { 464 stream.defaultWriteObject(); 465 } 466 } 467 } 468 469 static class SynchronizedRandomAccessList<E> extends SynchronizedList<E> 470 implements RandomAccess { 471 private static final long serialVersionUID = 1530674583602358482L; 472 473 SynchronizedRandomAccessList(List<E> l) { 474 super(l); 475 } 476 477 SynchronizedRandomAccessList(List<E> l, Object mutex) { 478 super(l, mutex); 479 } 480 481 @Override public List<E> subList(int start, int end) { 482 synchronized (mutex) { 483 return new SynchronizedRandomAccessList<E>(list.subList(start, end), mutex); 484 } 485 } 486 487 /** 488 * Replaces this SynchronizedRandomAccessList with a SynchronizedList so 489 * that JREs before 1.4 can deserialize this object without any 490 * problems. This is necessary since RandomAccess API was introduced 491 * only in 1.4. 492 * <p> 493 * 494 * @return SynchronizedList 495 * 496 * @see SynchronizedList#readResolve() 497 */ 498 private Object writeReplace() { 499 return new SynchronizedList<E>(list); 500 } 501 } 502 503 static class SynchronizedList<E> extends SynchronizedCollection<E> implements List<E> { 504 private static final long serialVersionUID = -7754090372962971524L; 505 final List<E> list; 506 507 SynchronizedList(List<E> l) { 508 super(l); 509 list = l; 510 } 511 512 SynchronizedList(List<E> l, Object mutex) { 513 super(l, mutex); 514 list = l; 515 } 516 517 @Override public void add(int location, E object) { 518 synchronized (mutex) { 519 list.add(location, object); 520 } 521 } 522 523 @Override public boolean addAll(int location, Collection<? extends E> collection) { 524 synchronized (mutex) { 525 return list.addAll(location, collection); 526 } 527 } 528 529 @Override public boolean equals(Object object) { 530 synchronized (mutex) { 531 return list.equals(object); 532 } 533 } 534 535 @Override public E get(int location) { 536 synchronized (mutex) { 537 return list.get(location); 538 } 539 } 540 541 @Override public int hashCode() { 542 synchronized (mutex) { 543 return list.hashCode(); 544 } 545 } 546 547 @Override public int indexOf(Object object) { 548 final int size; 549 final Object[] array; 550 synchronized (mutex) { 551 size = list.size(); 552 array = new Object[size]; 553 list.toArray(array); 554 } 555 if (object != null) { 556 for (int i = 0; i < size; i++) { 557 if (object.equals(array[i])) { 558 return i; 559 } 560 } 561 } else { 562 for (int i = 0; i < size; i++) { 563 if (array[i] == null) { 564 return i; 565 } 566 } 567 } 568 return -1; 569 } 570 571 @Override public int lastIndexOf(Object object) { 572 final int size; 573 final Object[] array; 574 synchronized (mutex) { 575 size = list.size(); 576 array = new Object[size]; 577 list.toArray(array); 578 } 579 if (object != null) { 580 for (int i = size - 1; i >= 0; i--) { 581 if (object.equals(array[i])) { 582 return i; 583 } 584 } 585 } else { 586 for (int i = size - 1; i >= 0; i--) { 587 if (array[i] == null) { 588 return i; 589 } 590 } 591 } 592 return -1; 593 } 594 595 @Override public ListIterator<E> listIterator() { 596 synchronized (mutex) { 597 return list.listIterator(); 598 } 599 } 600 601 @Override public ListIterator<E> listIterator(int location) { 602 synchronized (mutex) { 603 return list.listIterator(location); 604 } 605 } 606 607 @Override public E remove(int location) { 608 synchronized (mutex) { 609 return list.remove(location); 610 } 611 } 612 613 @Override public E set(int location, E object) { 614 synchronized (mutex) { 615 return list.set(location, object); 616 } 617 } 618 619 @Override public List<E> subList(int start, int end) { 620 synchronized (mutex) { 621 return new SynchronizedList<E>(list.subList(start, end), mutex); 622 } 623 } 624 625 private void writeObject(ObjectOutputStream stream) throws IOException { 626 synchronized (mutex) { 627 stream.defaultWriteObject(); 628 } 629 } 630 631 /** 632 * Resolves SynchronizedList instances to SynchronizedRandomAccessList 633 * instances if the underlying list is a Random Access list. 634 * <p> 635 * This is necessary since SynchronizedRandomAccessList instances are 636 * replaced with SynchronizedList instances during serialization for 637 * compliance with JREs before 1.4. 638 * <p> 639 * 640 * @return a SynchronizedList instance if the underlying list implements 641 * RandomAccess interface, or this same object if not. 642 * 643 * @see SynchronizedRandomAccessList#writeReplace() 644 */ 645 private Object readResolve() { 646 if (list instanceof RandomAccess) { 647 return new SynchronizedRandomAccessList<E>(list, mutex); 648 } 649 return this; 650 } 651 } 652 653 static class SynchronizedMap<K, V> implements Map<K, V>, Serializable { 654 private static final long serialVersionUID = 1978198479659022715L; 655 656 private final Map<K, V> m; 657 658 final Object mutex; 659 660 SynchronizedMap(Map<K, V> map) { 661 m = map; 662 mutex = this; 663 } 664 665 SynchronizedMap(Map<K, V> map, Object mutex) { 666 m = map; 667 this.mutex = mutex; 668 } 669 670 @Override public void clear() { 671 synchronized (mutex) { 672 m.clear(); 673 } 674 } 675 676 @Override public boolean containsKey(Object key) { 677 synchronized (mutex) { 678 return m.containsKey(key); 679 } 680 } 681 682 @Override public boolean containsValue(Object value) { 683 synchronized (mutex) { 684 return m.containsValue(value); 685 } 686 } 687 688 @Override public Set<Map.Entry<K, V>> entrySet() { 689 synchronized (mutex) { 690 return new SynchronizedSet<Map.Entry<K, V>>(m.entrySet(), mutex); 691 } 692 } 693 694 @Override public boolean equals(Object object) { 695 synchronized (mutex) { 696 return m.equals(object); 697 } 698 } 699 700 @Override public V get(Object key) { 701 synchronized (mutex) { 702 return m.get(key); 703 } 704 } 705 706 @Override public int hashCode() { 707 synchronized (mutex) { 708 return m.hashCode(); 709 } 710 } 711 712 @Override public boolean isEmpty() { 713 synchronized (mutex) { 714 return m.isEmpty(); 715 } 716 } 717 718 @Override public Set<K> keySet() { 719 synchronized (mutex) { 720 return new SynchronizedSet<K>(m.keySet(), mutex); 721 } 722 } 723 724 @Override public V put(K key, V value) { 725 synchronized (mutex) { 726 return m.put(key, value); 727 } 728 } 729 730 @Override public void putAll(Map<? extends K, ? extends V> map) { 731 synchronized (mutex) { 732 m.putAll(map); 733 } 734 } 735 736 @Override public V remove(Object key) { 737 synchronized (mutex) { 738 return m.remove(key); 739 } 740 } 741 742 @Override public int size() { 743 synchronized (mutex) { 744 return m.size(); 745 } 746 } 747 748 @Override public Collection<V> values() { 749 synchronized (mutex) { 750 return new SynchronizedCollection<V>(m.values(), mutex); 751 } 752 } 753 754 @Override public String toString() { 755 synchronized (mutex) { 756 return m.toString(); 757 } 758 } 759 760 private void writeObject(ObjectOutputStream stream) throws IOException { 761 synchronized (mutex) { 762 stream.defaultWriteObject(); 763 } 764 } 765 } 766 767 static class SynchronizedSet<E> extends SynchronizedCollection<E> implements Set<E> { 768 private static final long serialVersionUID = 487447009682186044L; 769 770 SynchronizedSet(Set<E> set) { 771 super(set); 772 } 773 774 SynchronizedSet(Set<E> set, Object mutex) { 775 super(set, mutex); 776 } 777 778 @Override public boolean equals(Object object) { 779 synchronized (mutex) { 780 return c.equals(object); 781 } 782 } 783 784 @Override public int hashCode() { 785 synchronized (mutex) { 786 return c.hashCode(); 787 } 788 } 789 790 private void writeObject(ObjectOutputStream stream) throws IOException { 791 synchronized (mutex) { 792 stream.defaultWriteObject(); 793 } 794 } 795 } 796 797 static class SynchronizedSortedMap<K, V> extends SynchronizedMap<K, V> 798 implements SortedMap<K, V> { 799 private static final long serialVersionUID = -8798146769416483793L; 800 801 private final SortedMap<K, V> sm; 802 803 SynchronizedSortedMap(SortedMap<K, V> map) { 804 super(map); 805 sm = map; 806 } 807 808 SynchronizedSortedMap(SortedMap<K, V> map, Object mutex) { 809 super(map, mutex); 810 sm = map; 811 } 812 813 @Override public Comparator<? super K> comparator() { 814 synchronized (mutex) { 815 return sm.comparator(); 816 } 817 } 818 819 @Override public K firstKey() { 820 synchronized (mutex) { 821 return sm.firstKey(); 822 } 823 } 824 825 @Override public SortedMap<K, V> headMap(K endKey) { 826 synchronized (mutex) { 827 return new SynchronizedSortedMap<K, V>(sm.headMap(endKey), 828 mutex); 829 } 830 } 831 832 @Override public K lastKey() { 833 synchronized (mutex) { 834 return sm.lastKey(); 835 } 836 } 837 838 @Override public SortedMap<K, V> subMap(K startKey, K endKey) { 839 synchronized (mutex) { 840 return new SynchronizedSortedMap<K, V>(sm.subMap(startKey, 841 endKey), mutex); 842 } 843 } 844 845 @Override public SortedMap<K, V> tailMap(K startKey) { 846 synchronized (mutex) { 847 return new SynchronizedSortedMap<K, V>(sm.tailMap(startKey), 848 mutex); 849 } 850 } 851 852 private void writeObject(ObjectOutputStream stream) throws IOException { 853 synchronized (mutex) { 854 stream.defaultWriteObject(); 855 } 856 } 857 } 858 859 static class SynchronizedSortedSet<E> extends SynchronizedSet<E> implements SortedSet<E> { 860 private static final long serialVersionUID = 8695801310862127406L; 861 862 private final SortedSet<E> ss; 863 864 SynchronizedSortedSet(SortedSet<E> set) { 865 super(set); 866 ss = set; 867 } 868 869 SynchronizedSortedSet(SortedSet<E> set, Object mutex) { 870 super(set, mutex); 871 ss = set; 872 } 873 874 @Override public Comparator<? super E> comparator() { 875 synchronized (mutex) { 876 return ss.comparator(); 877 } 878 } 879 880 @Override public E first() { 881 synchronized (mutex) { 882 return ss.first(); 883 } 884 } 885 886 @Override public SortedSet<E> headSet(E end) { 887 synchronized (mutex) { 888 return new SynchronizedSortedSet<E>(ss.headSet(end), mutex); 889 } 890 } 891 892 @Override public E last() { 893 synchronized (mutex) { 894 return ss.last(); 895 } 896 } 897 898 @Override public SortedSet<E> subSet(E start, E end) { 899 synchronized (mutex) { 900 return new SynchronizedSortedSet<E>(ss.subSet(start, end), 901 mutex); 902 } 903 } 904 905 @Override public SortedSet<E> tailSet(E start) { 906 synchronized (mutex) { 907 return new SynchronizedSortedSet<E>(ss.tailSet(start), mutex); 908 } 909 } 910 911 private void writeObject(ObjectOutputStream stream) throws IOException { 912 synchronized (mutex) { 913 stream.defaultWriteObject(); 914 } 915 } 916 } 917 918 private static class UnmodifiableCollection<E> implements Collection<E>, Serializable { 919 private static final long serialVersionUID = 1820017752578914078L; 920 921 final Collection<E> c; 922 923 UnmodifiableCollection(Collection<E> collection) { 924 c = collection; 925 } 926 927 @Override public boolean add(E object) { 928 throw new UnsupportedOperationException(); 929 } 930 931 @Override public boolean addAll(Collection<? extends E> collection) { 932 throw new UnsupportedOperationException(); 933 } 934 935 @Override public void clear() { 936 throw new UnsupportedOperationException(); 937 } 938 939 @Override public boolean contains(Object object) { 940 return c.contains(object); 941 } 942 943 @Override public boolean containsAll(Collection<?> collection) { 944 return c.containsAll(collection); 945 } 946 947 @Override public boolean isEmpty() { 948 return c.isEmpty(); 949 } 950 951 @Override public Iterator<E> iterator() { 952 return new Iterator<E>() { 953 Iterator<E> iterator = c.iterator(); 954 955 @Override public boolean hasNext() { 956 return iterator.hasNext(); 957 } 958 959 @Override public E next() { 960 return iterator.next(); 961 } 962 963 @Override public void remove() { 964 throw new UnsupportedOperationException(); 965 } 966 }; 967 } 968 969 @Override public boolean remove(Object object) { 970 throw new UnsupportedOperationException(); 971 } 972 973 @Override public boolean removeAll(Collection<?> collection) { 974 throw new UnsupportedOperationException(); 975 } 976 977 @Override public boolean retainAll(Collection<?> collection) { 978 throw new UnsupportedOperationException(); 979 } 980 981 @Override public int size() { 982 return c.size(); 983 } 984 985 @Override public Object[] toArray() { 986 return c.toArray(); 987 } 988 989 @Override public <T> T[] toArray(T[] array) { 990 return c.toArray(array); 991 } 992 993 @Override public String toString() { 994 return c.toString(); 995 } 996 } 997 998 private static class UnmodifiableRandomAccessList<E> extends UnmodifiableList<E> 999 implements RandomAccess { 1000 private static final long serialVersionUID = -2542308836966382001L; 1001 1002 UnmodifiableRandomAccessList(List<E> l) { 1003 super(l); 1004 } 1005 1006 @Override public List<E> subList(int start, int end) { 1007 return new UnmodifiableRandomAccessList<E>(list.subList(start, end)); 1008 } 1009 1010 /** 1011 * Replaces this UnmodifiableRandomAccessList with an UnmodifiableList 1012 * so that JREs before 1.4 can deserialize this object without any 1013 * problems. This is necessary since RandomAccess API was introduced 1014 * only in 1.4. 1015 * <p> 1016 * 1017 * @return UnmodifiableList 1018 * 1019 * @see UnmodifiableList#readResolve() 1020 */ 1021 private Object writeReplace() { 1022 return new UnmodifiableList<E>(list); 1023 } 1024 } 1025 1026 private static class UnmodifiableList<E> extends UnmodifiableCollection<E> 1027 implements List<E> { 1028 private static final long serialVersionUID = -283967356065247728L; 1029 1030 final List<E> list; 1031 1032 UnmodifiableList(List<E> l) { 1033 super(l); 1034 list = l; 1035 } 1036 1037 @Override public void add(int location, E object) { 1038 throw new UnsupportedOperationException(); 1039 } 1040 1041 @Override public boolean addAll(int location, Collection<? extends E> collection) { 1042 throw new UnsupportedOperationException(); 1043 } 1044 1045 @Override public boolean equals(Object object) { 1046 return list.equals(object); 1047 } 1048 1049 @Override public E get(int location) { 1050 return list.get(location); 1051 } 1052 1053 @Override public int hashCode() { 1054 return list.hashCode(); 1055 } 1056 1057 @Override public int indexOf(Object object) { 1058 return list.indexOf(object); 1059 } 1060 1061 @Override public int lastIndexOf(Object object) { 1062 return list.lastIndexOf(object); 1063 } 1064 1065 @Override public ListIterator<E> listIterator() { 1066 return listIterator(0); 1067 } 1068 1069 @Override public ListIterator<E> listIterator(final int location) { 1070 return new ListIterator<E>() { 1071 ListIterator<E> iterator = list.listIterator(location); 1072 1073 @Override public void add(E object) { 1074 throw new UnsupportedOperationException(); 1075 } 1076 1077 @Override public boolean hasNext() { 1078 return iterator.hasNext(); 1079 } 1080 1081 @Override public boolean hasPrevious() { 1082 return iterator.hasPrevious(); 1083 } 1084 1085 @Override public E next() { 1086 return iterator.next(); 1087 } 1088 1089 @Override public int nextIndex() { 1090 return iterator.nextIndex(); 1091 } 1092 1093 @Override public E previous() { 1094 return iterator.previous(); 1095 } 1096 1097 @Override public int previousIndex() { 1098 return iterator.previousIndex(); 1099 } 1100 1101 @Override public void remove() { 1102 throw new UnsupportedOperationException(); 1103 } 1104 1105 @Override public void set(E object) { 1106 throw new UnsupportedOperationException(); 1107 } 1108 }; 1109 } 1110 1111 @Override public E remove(int location) { 1112 throw new UnsupportedOperationException(); 1113 } 1114 1115 @Override public E set(int location, E object) { 1116 throw new UnsupportedOperationException(); 1117 } 1118 1119 @Override public List<E> subList(int start, int end) { 1120 return new UnmodifiableList<E>(list.subList(start, end)); 1121 } 1122 1123 /** 1124 * Resolves UnmodifiableList instances to UnmodifiableRandomAccessList 1125 * instances if the underlying list is a Random Access list. 1126 * <p> 1127 * This is necessary since UnmodifiableRandomAccessList instances are 1128 * replaced with UnmodifiableList instances during serialization for 1129 * compliance with JREs before 1.4. 1130 * <p> 1131 * 1132 * @return an UnmodifiableList instance if the underlying list 1133 * implements RandomAccess interface, or this same object if 1134 * not. 1135 * 1136 * @see UnmodifiableRandomAccessList#writeReplace() 1137 */ 1138 private Object readResolve() { 1139 if (list instanceof RandomAccess) { 1140 return new UnmodifiableRandomAccessList<E>(list); 1141 } 1142 return this; 1143 } 1144 } 1145 1146 private static class UnmodifiableMap<K, V> implements Map<K, V>, 1147 Serializable { 1148 private static final long serialVersionUID = -1034234728574286014L; 1149 1150 private final Map<K, V> m; 1151 1152 private static class UnmodifiableEntrySet<K, V> extends 1153 UnmodifiableSet<Map.Entry<K, V>> { 1154 private static final long serialVersionUID = 7854390611657943733L; 1155 1156 private static class UnmodifiableMapEntry<K, V> implements 1157 Map.Entry<K, V> { 1158 Map.Entry<K, V> mapEntry; 1159 1160 UnmodifiableMapEntry(Map.Entry<K, V> entry) { 1161 mapEntry = entry; 1162 } 1163 1164 @Override public boolean equals(Object object) { 1165 return mapEntry.equals(object); 1166 } 1167 1168 @Override public K getKey() { 1169 return mapEntry.getKey(); 1170 } 1171 1172 @Override public V getValue() { 1173 return mapEntry.getValue(); 1174 } 1175 1176 @Override public int hashCode() { 1177 return mapEntry.hashCode(); 1178 } 1179 1180 @Override public V setValue(V object) { 1181 throw new UnsupportedOperationException(); 1182 } 1183 1184 @Override public String toString() { 1185 return mapEntry.toString(); 1186 } 1187 } 1188 1189 UnmodifiableEntrySet(Set<Map.Entry<K, V>> set) { 1190 super(set); 1191 } 1192 1193 @Override public Iterator<Map.Entry<K, V>> iterator() { 1194 return new Iterator<Map.Entry<K, V>>() { 1195 Iterator<Map.Entry<K, V>> iterator = c.iterator(); 1196 1197 @Override public boolean hasNext() { 1198 return iterator.hasNext(); 1199 } 1200 1201 @Override public Map.Entry<K, V> next() { 1202 return new UnmodifiableMapEntry<K, V>(iterator.next()); 1203 } 1204 1205 @Override public void remove() { 1206 throw new UnsupportedOperationException(); 1207 } 1208 }; 1209 } 1210 1211 @Override public Object[] toArray() { 1212 int length = c.size(); 1213 Object[] result = new Object[length]; 1214 Iterator<?> it = iterator(); 1215 for (int i = length; --i >= 0;) { 1216 result[i] = it.next(); 1217 } 1218 return result; 1219 } 1220 1221 @SuppressWarnings("unchecked") 1222 @Override public <T> T[] toArray(T[] contents) { 1223 int size = c.size(), index = 0; 1224 Iterator<Map.Entry<K, V>> it = iterator(); 1225 if (size > contents.length) { 1226 Class<?> ct = contents.getClass().getComponentType(); 1227 contents = (T[]) Array.newInstance(ct, size); 1228 } 1229 while (index < size) { 1230 contents[index++] = (T) it.next(); 1231 } 1232 if (index < contents.length) { 1233 contents[index] = null; 1234 } 1235 return contents; 1236 } 1237 } 1238 1239 UnmodifiableMap(Map<K, V> map) { 1240 m = map; 1241 } 1242 1243 @Override public void clear() { 1244 throw new UnsupportedOperationException(); 1245 } 1246 1247 @Override public boolean containsKey(Object key) { 1248 return m.containsKey(key); 1249 } 1250 1251 @Override public boolean containsValue(Object value) { 1252 return m.containsValue(value); 1253 } 1254 1255 @Override public Set<Map.Entry<K, V>> entrySet() { 1256 return new UnmodifiableEntrySet<K, V>(m.entrySet()); 1257 } 1258 1259 @Override public boolean equals(Object object) { 1260 return m.equals(object); 1261 } 1262 1263 @Override public V get(Object key) { 1264 return m.get(key); 1265 } 1266 1267 @Override public int hashCode() { 1268 return m.hashCode(); 1269 } 1270 1271 @Override public boolean isEmpty() { 1272 return m.isEmpty(); 1273 } 1274 1275 @Override public Set<K> keySet() { 1276 return new UnmodifiableSet<K>(m.keySet()); 1277 } 1278 1279 @Override public V put(K key, V value) { 1280 throw new UnsupportedOperationException(); 1281 } 1282 1283 @Override public void putAll(Map<? extends K, ? extends V> map) { 1284 throw new UnsupportedOperationException(); 1285 } 1286 1287 @Override public V remove(Object key) { 1288 throw new UnsupportedOperationException(); 1289 } 1290 1291 @Override public int size() { 1292 return m.size(); 1293 } 1294 1295 @Override public Collection<V> values() { 1296 return new UnmodifiableCollection<V>(m.values()); 1297 } 1298 1299 @Override public String toString() { 1300 return m.toString(); 1301 } 1302 } 1303 1304 private static class UnmodifiableSet<E> extends UnmodifiableCollection<E> 1305 implements Set<E> { 1306 private static final long serialVersionUID = -9215047833775013803L; 1307 1308 UnmodifiableSet(Set<E> set) { 1309 super(set); 1310 } 1311 1312 @Override public boolean equals(Object object) { 1313 return c.equals(object); 1314 } 1315 1316 @Override public int hashCode() { 1317 return c.hashCode(); 1318 } 1319 } 1320 1321 private static class UnmodifiableSortedMap<K, V> extends 1322 UnmodifiableMap<K, V> implements SortedMap<K, V> { 1323 private static final long serialVersionUID = -8806743815996713206L; 1324 1325 private final SortedMap<K, V> sm; 1326 1327 UnmodifiableSortedMap(SortedMap<K, V> map) { 1328 super(map); 1329 sm = map; 1330 } 1331 1332 @Override public Comparator<? super K> comparator() { 1333 return sm.comparator(); 1334 } 1335 1336 @Override public K firstKey() { 1337 return sm.firstKey(); 1338 } 1339 1340 @Override public SortedMap<K, V> headMap(K before) { 1341 return new UnmodifiableSortedMap<K, V>(sm.headMap(before)); 1342 } 1343 1344 @Override public K lastKey() { 1345 return sm.lastKey(); 1346 } 1347 1348 @Override public SortedMap<K, V> subMap(K start, K end) { 1349 return new UnmodifiableSortedMap<K, V>(sm.subMap(start, end)); 1350 } 1351 1352 @Override public SortedMap<K, V> tailMap(K after) { 1353 return new UnmodifiableSortedMap<K, V>(sm.tailMap(after)); 1354 } 1355 } 1356 1357 private static class UnmodifiableSortedSet<E> extends UnmodifiableSet<E> 1358 implements SortedSet<E> { 1359 private static final long serialVersionUID = -4929149591599911165L; 1360 1361 private final SortedSet<E> ss; 1362 1363 UnmodifiableSortedSet(SortedSet<E> set) { 1364 super(set); 1365 ss = set; 1366 } 1367 1368 @Override public Comparator<? super E> comparator() { 1369 return ss.comparator(); 1370 } 1371 1372 @Override public E first() { 1373 return ss.first(); 1374 } 1375 1376 @Override public SortedSet<E> headSet(E before) { 1377 return new UnmodifiableSortedSet<E>(ss.headSet(before)); 1378 } 1379 1380 @Override public E last() { 1381 return ss.last(); 1382 } 1383 1384 @Override public SortedSet<E> subSet(E start, E end) { 1385 return new UnmodifiableSortedSet<E>(ss.subSet(start, end)); 1386 } 1387 1388 @Override public SortedSet<E> tailSet(E after) { 1389 return new UnmodifiableSortedSet<E>(ss.tailSet(after)); 1390 } 1391 } 1392 1393 private Collections() {} 1394 1395 /** 1396 * Performs a binary search for the specified element in the specified 1397 * sorted list. The list needs to be already sorted in natural sorting 1398 * order. Searching in an unsorted array has an undefined result. It's also 1399 * undefined which element is found if there are multiple occurrences of the 1400 * same element. 1401 * 1402 * @param list 1403 * the sorted list to search. 1404 * @param object 1405 * the element to find. 1406 * @return the non-negative index of the element, or a negative index which 1407 * is the {@code -index - 1} where the element would be inserted 1408 * @throws ClassCastException 1409 * if an element in the List or the search element does not 1410 * implement Comparable, or cannot be compared to each other. 1411 */ 1412 @SuppressWarnings("unchecked") 1413 public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T object) { 1414 if (list == null) { 1415 throw new NullPointerException("list == null"); 1416 } 1417 if (list.isEmpty()) { 1418 return -1; 1419 } 1420 1421 1422 if (!(list instanceof RandomAccess)) { 1423 ListIterator<? extends Comparable<? super T>> it = list.listIterator(); 1424 while (it.hasNext()) { 1425 int result; 1426 if ((result = -it.next().compareTo(object)) <= 0) { 1427 if (result == 0) { 1428 return it.previousIndex(); 1429 } 1430 return -it.previousIndex() - 1; 1431 } 1432 } 1433 return -list.size() - 1; 1434 } 1435 1436 int low = 0, mid = list.size(), high = mid - 1, result = -1; 1437 while (low <= high) { 1438 mid = (low + high) >>> 1; 1439 if ((result = -list.get(mid).compareTo(object)) > 0) { 1440 low = mid + 1; 1441 } else if (result == 0) { 1442 return mid; 1443 } else { 1444 high = mid - 1; 1445 } 1446 } 1447 return -mid - (result < 0 ? 1 : 2); 1448 } 1449 1450 /** 1451 * Performs a binary search for the specified element in the specified 1452 * sorted list using the specified comparator. The list needs to be already 1453 * sorted according to the comparator passed. Searching in an unsorted array 1454 * has an undefined result. It's also undefined which element is found if 1455 * there are multiple occurrences of the same element. 1456 * 1457 * @param list 1458 * the sorted List to search. 1459 * @param object 1460 * the element to find. 1461 * @param comparator 1462 * the comparator. If the comparator is {@code null} then the 1463 * search uses the objects' natural ordering. 1464 * @return the non-negative index of the element, or a negative index which 1465 * is the {@code -index - 1} where the element would be inserted. 1466 * @throws ClassCastException 1467 * when an element in the list and the searched element cannot 1468 * be compared to each other using the comparator. 1469 */ 1470 @SuppressWarnings("unchecked") 1471 public static <T> int binarySearch(List<? extends T> list, T object, 1472 Comparator<? super T> comparator) { 1473 if (comparator == null) { 1474 return Collections.binarySearch( 1475 (List<? extends Comparable<? super T>>) list, object); 1476 } 1477 if (!(list instanceof RandomAccess)) { 1478 ListIterator<? extends T> it = list.listIterator(); 1479 while (it.hasNext()) { 1480 int result; 1481 if ((result = -comparator.compare(it.next(), object)) <= 0) { 1482 if (result == 0) { 1483 return it.previousIndex(); 1484 } 1485 return -it.previousIndex() - 1; 1486 } 1487 } 1488 return -list.size() - 1; 1489 } 1490 1491 int low = 0, mid = list.size(), high = mid - 1, result = -1; 1492 while (low <= high) { 1493 mid = (low + high) >>> 1; 1494 if ((result = -comparator.compare(list.get(mid), object)) > 0) { 1495 low = mid + 1; 1496 } else if (result == 0) { 1497 return mid; 1498 } else { 1499 high = mid - 1; 1500 } 1501 } 1502 return -mid - (result < 0 ? 1 : 2); 1503 } 1504 1505 /** 1506 * Copies the elements from the source list to the destination list. At the 1507 * end both lists will have the same objects at the same index. If the 1508 * destination array is larger than the source list, the elements in the 1509 * destination list with {@code index >= source.size()} will be unchanged. 1510 * 1511 * @param destination 1512 * the list whose elements are set from the source list. 1513 * @param source 1514 * the list with the elements to be copied into the destination. 1515 * @throws IndexOutOfBoundsException 1516 * when the destination list is smaller than the source list. 1517 * @throws UnsupportedOperationException 1518 * when replacing an element in the destination list is not 1519 * supported. 1520 */ 1521 public static <T> void copy(List<? super T> destination, List<? extends T> source) { 1522 if (destination.size() < source.size()) { 1523 throw new IndexOutOfBoundsException("destination.size() < source.size(): " + 1524 destination.size() + " < " + source.size()); 1525 } 1526 Iterator<? extends T> srcIt = source.iterator(); 1527 ListIterator<? super T> destIt = destination.listIterator(); 1528 while (srcIt.hasNext()) { 1529 try { 1530 destIt.next(); 1531 } catch (NoSuchElementException e) { 1532 // TODO: AssertionError? 1533 throw new IndexOutOfBoundsException("Source size " + source.size() + 1534 " does not fit into destination"); 1535 } 1536 destIt.set(srcIt.next()); 1537 } 1538 } 1539 1540 /** 1541 * Returns an {@code Enumeration} on the specified collection. 1542 * 1543 * @param collection 1544 * the collection to enumerate. 1545 * @return an Enumeration. 1546 */ 1547 public static <T> Enumeration<T> enumeration(Collection<T> collection) { 1548 final Collection<T> c = collection; 1549 return new Enumeration<T>() { 1550 Iterator<T> it = c.iterator(); 1551 1552 @Override public boolean hasMoreElements() { 1553 return it.hasNext(); 1554 } 1555 1556 @Override public T nextElement() { 1557 return it.next(); 1558 } 1559 }; 1560 } 1561 1562 /** 1563 * Fills the specified list with the specified element. 1564 * 1565 * @param list 1566 * the list to fill. 1567 * @param object 1568 * the element to fill the list with. 1569 * @throws UnsupportedOperationException 1570 * when replacing an element in the List is not supported. 1571 */ 1572 public static <T> void fill(List<? super T> list, T object) { 1573 ListIterator<? super T> it = list.listIterator(); 1574 while (it.hasNext()) { 1575 it.next(); 1576 it.set(object); 1577 } 1578 } 1579 1580 /** 1581 * Searches the specified collection for the maximum element. 1582 * 1583 * @param collection 1584 * the collection to search. 1585 * @return the maximum element in the Collection. 1586 * @throws ClassCastException 1587 * when an element in the collection does not implement 1588 * {@code Comparable} or elements cannot be compared to each 1589 * other. 1590 */ 1591 public static <T extends Object & Comparable<? super T>> T max( 1592 Collection<? extends T> collection) { 1593 Iterator<? extends T> it = collection.iterator(); 1594 T max = it.next(); 1595 while (it.hasNext()) { 1596 T next = it.next(); 1597 if (max.compareTo(next) < 0) { 1598 max = next; 1599 } 1600 } 1601 return max; 1602 } 1603 1604 /** 1605 * Searches the specified collection for the maximum element using the 1606 * specified comparator. 1607 * 1608 * @param collection 1609 * the collection to search. 1610 * @param comparator 1611 * the comparator. 1612 * @return the maximum element in the Collection. 1613 * @throws ClassCastException 1614 * when elements in the collection cannot be compared to each 1615 * other using the {@code Comparator}. 1616 */ 1617 public static <T> T max(Collection<? extends T> collection, 1618 Comparator<? super T> comparator) { 1619 if (comparator == null) { 1620 @SuppressWarnings("unchecked") // null comparator? T is comparable 1621 T result = (T) max((Collection<Comparable>) collection); 1622 return result; 1623 } 1624 1625 Iterator<? extends T> it = collection.iterator(); 1626 T max = it.next(); 1627 while (it.hasNext()) { 1628 T next = it.next(); 1629 if (comparator.compare(max, next) < 0) { 1630 max = next; 1631 } 1632 } 1633 return max; 1634 } 1635 1636 /** 1637 * Searches the specified collection for the minimum element. 1638 * 1639 * @param collection 1640 * the collection to search. 1641 * @return the minimum element in the collection. 1642 * @throws ClassCastException 1643 * when an element in the collection does not implement 1644 * {@code Comparable} or elements cannot be compared to each 1645 * other. 1646 */ 1647 public static <T extends Object & Comparable<? super T>> T min( 1648 Collection<? extends T> collection) { 1649 Iterator<? extends T> it = collection.iterator(); 1650 T min = it.next(); 1651 while (it.hasNext()) { 1652 T next = it.next(); 1653 if (min.compareTo(next) > 0) { 1654 min = next; 1655 } 1656 } 1657 return min; 1658 } 1659 1660 /** 1661 * Searches the specified collection for the minimum element using the 1662 * specified comparator. 1663 * 1664 * @param collection 1665 * the collection to search. 1666 * @param comparator 1667 * the comparator. 1668 * @return the minimum element in the collection. 1669 * @throws ClassCastException 1670 * when elements in the collection cannot be compared to each 1671 * other using the {@code Comparator}. 1672 */ 1673 public static <T> T min(Collection<? extends T> collection, 1674 Comparator<? super T> comparator) { 1675 if (comparator == null) { 1676 @SuppressWarnings("unchecked") // null comparator? T is comparable 1677 T result = (T) min((Collection<Comparable>) collection); 1678 return result; 1679 } 1680 1681 Iterator<? extends T> it = collection.iterator(); 1682 T min = it.next(); 1683 while (it.hasNext()) { 1684 T next = it.next(); 1685 if (comparator.compare(min, next) > 0) { 1686 min = next; 1687 } 1688 } 1689 return min; 1690 } 1691 1692 /** 1693 * Returns a list containing the specified number of the specified element. 1694 * The list cannot be modified. The list is serializable. 1695 * 1696 * @param length 1697 * the size of the returned list. 1698 * @param object 1699 * the element to be added {@code length} times to a list. 1700 * @return a list containing {@code length} copies of the element. 1701 * @throws IllegalArgumentException 1702 * when {@code length < 0}. 1703 */ 1704 public static <T> List<T> nCopies(final int length, T object) { 1705 return new CopiesList<T>(length, object); 1706 } 1707 1708 /** 1709 * Modifies the specified {@code List} by reversing the order of the 1710 * elements. 1711 * 1712 * @param list 1713 * the list to reverse. 1714 * @throws UnsupportedOperationException 1715 * when replacing an element in the List is not supported. 1716 */ 1717 @SuppressWarnings("unchecked") 1718 public static void reverse(List<?> list) { 1719 int size = list.size(); 1720 ListIterator<Object> front = (ListIterator<Object>) list.listIterator(); 1721 ListIterator<Object> back = (ListIterator<Object>) list 1722 .listIterator(size); 1723 for (int i = 0; i < size / 2; i++) { 1724 Object frontNext = front.next(); 1725 Object backPrev = back.previous(); 1726 front.set(backPrev); 1727 back.set(frontNext); 1728 } 1729 } 1730 1731 /** 1732 * A comparator which reverses the natural order of the elements. The 1733 * {@code Comparator} that's returned is {@link Serializable}. 1734 * 1735 * @return a {@code Comparator} instance. 1736 */ 1737 @SuppressWarnings("unchecked") 1738 public static <T> Comparator<T> reverseOrder() { 1739 return (Comparator) ReverseComparator.INSTANCE; 1740 } 1741 1742 /** 1743 * Returns a {@link Comparator} that reverses the order of the 1744 * {@code Comparator} passed. If the {@code Comparator} passed is 1745 * {@code null}, then this method is equivalent to {@link #reverseOrder()}. 1746 * <p> 1747 * The {@code Comparator} that's returned is {@link Serializable} if the 1748 * {@code Comparator} passed is serializable or {@code null}. 1749 * 1750 * @param c 1751 * the {@code Comparator} to reverse or {@code null}. 1752 * @return a {@code Comparator} instance. 1753 * @since 1.5 1754 */ 1755 public static <T> Comparator<T> reverseOrder(Comparator<T> c) { 1756 if (c == null) { 1757 return reverseOrder(); 1758 } 1759 if (c instanceof ReverseComparator2) { 1760 return ((ReverseComparator2<T>) c).cmp; 1761 } 1762 return new ReverseComparator2<T>(c); 1763 } 1764 1765 /** 1766 * Moves every element of the list to a random new position in the list. 1767 * 1768 * @param list 1769 * the List to shuffle. 1770 * 1771 * @throws UnsupportedOperationException 1772 * when replacing an element in the List is not supported. 1773 */ 1774 public static void shuffle(List<?> list) { 1775 shuffle(list, new Random()); 1776 } 1777 1778 /** 1779 * Moves every element of the list to a random new position in the list 1780 * using the specified random number generator. 1781 * 1782 * @param list 1783 * the list to shuffle. 1784 * @param random 1785 * the random number generator. 1786 * @throws UnsupportedOperationException 1787 * when replacing an element in the list is not supported. 1788 */ 1789 public static void shuffle(List<?> list, Random random) { 1790 @SuppressWarnings("unchecked") // we won't put foreign objects in 1791 final List<Object> objectList = (List<Object>) list; 1792 1793 if (list instanceof RandomAccess) { 1794 for (int i = objectList.size() - 1; i > 0; i--) { 1795 int index = random.nextInt(i + 1); 1796 objectList.set(index, objectList.set(i, objectList.get(index))); 1797 } 1798 } else { 1799 Object[] array = objectList.toArray(); 1800 for (int i = array.length - 1; i > 0; i--) { 1801 int index = random.nextInt(i + 1); 1802 Object temp = array[i]; 1803 array[i] = array[index]; 1804 array[index] = temp; 1805 } 1806 1807 int i = 0; 1808 ListIterator<Object> it = objectList.listIterator(); 1809 while (it.hasNext()) { 1810 it.next(); 1811 it.set(array[i++]); 1812 } 1813 } 1814 } 1815 1816 /** 1817 * Returns a set containing the specified element. The set cannot be 1818 * modified. The set is serializable. 1819 * 1820 * @param object 1821 * the element. 1822 * @return a set containing the element. 1823 */ 1824 public static <E> Set<E> singleton(E object) { 1825 return new SingletonSet<E>(object); 1826 } 1827 1828 /** 1829 * Returns a list containing the specified element. The list cannot be 1830 * modified. The list is serializable. 1831 * 1832 * @param object 1833 * the element. 1834 * @return a list containing the element. 1835 */ 1836 public static <E> List<E> singletonList(E object) { 1837 return new SingletonList<E>(object); 1838 } 1839 1840 /** 1841 * Returns a Map containing the specified key and value. The map cannot be 1842 * modified. The map is serializable. 1843 * 1844 * @param key 1845 * the key. 1846 * @param value 1847 * the value. 1848 * @return a Map containing the key and value. 1849 */ 1850 public static <K, V> Map<K, V> singletonMap(K key, V value) { 1851 return new SingletonMap<K, V>(key, value); 1852 } 1853 1854 /** 1855 * Sorts the given list in ascending natural order. The algorithm is 1856 * stable which means equal elements don't get reordered. 1857 * 1858 * @throws ClassCastException if any element does not implement {@code Comparable}, 1859 * or if {@code compareTo} throws for any pair of elements. 1860 */ 1861 @SuppressWarnings("unchecked") 1862 public static <T extends Comparable<? super T>> void sort(List<T> list) { 1863 Object[] array = list.toArray(); 1864 Arrays.sort(array); 1865 int i = 0; 1866 ListIterator<T> it = list.listIterator(); 1867 while (it.hasNext()) { 1868 it.next(); 1869 it.set((T) array[i++]); 1870 } 1871 } 1872 1873 /** 1874 * Sorts the given list using the given comparator. The algorithm is 1875 * stable which means equal elements don't get reordered. 1876 * 1877 * @throws ClassCastException if any element does not implement {@code Comparable}, 1878 * or if {@code compareTo} throws for any pair of elements. 1879 */ 1880 @SuppressWarnings("unchecked") 1881 public static <T> void sort(List<T> list, Comparator<? super T> comparator) { 1882 T[] array = list.toArray((T[]) new Object[list.size()]); 1883 Arrays.sort(array, comparator); 1884 int i = 0; 1885 ListIterator<T> it = list.listIterator(); 1886 while (it.hasNext()) { 1887 it.next(); 1888 it.set(array[i++]); 1889 } 1890 } 1891 1892 /** 1893 * Swaps the elements of list {@code list} at indices {@code index1} and 1894 * {@code index2}. 1895 * 1896 * @param list 1897 * the list to manipulate. 1898 * @param index1 1899 * position of the first element to swap with the element in 1900 * index2. 1901 * @param index2 1902 * position of the other element. 1903 * 1904 * @throws IndexOutOfBoundsException 1905 * if index1 or index2 is out of range of this list. 1906 * @since 1.4 1907 */ 1908 @SuppressWarnings("unchecked") 1909 public static void swap(List<?> list, int index1, int index2) { 1910 if (list == null) { 1911 throw new NullPointerException("list == null"); 1912 } 1913 final int size = list.size(); 1914 if (index1 < 0 || index1 >= size || index2 < 0 || index2 >= size) { 1915 throw new IndexOutOfBoundsException(); 1916 } 1917 if (index1 == index2) { 1918 return; 1919 } 1920 List<Object> rawList = (List<Object>) list; 1921 rawList.set(index2, rawList.set(index1, rawList.get(index2))); 1922 } 1923 1924 /** 1925 * Replaces all occurrences of Object {@code obj} in {@code list} with 1926 * {@code newObj}. If the {@code obj} is {@code null}, then all 1927 * occurrences of {@code null} are replaced with {@code newObj}. 1928 * 1929 * @param list 1930 * the list to modify. 1931 * @param obj 1932 * the object to find and replace occurrences of. 1933 * @param obj2 1934 * the object to replace all occurrences of {@code obj} in 1935 * {@code list}. 1936 * @return true, if at least one occurrence of {@code obj} has been found in 1937 * {@code list}. 1938 * @throws UnsupportedOperationException 1939 * if the list does not support setting elements. 1940 */ 1941 public static <T> boolean replaceAll(List<T> list, T obj, T obj2) { 1942 int index; 1943 boolean found = false; 1944 1945 while ((index = list.indexOf(obj)) > -1) { 1946 found = true; 1947 list.set(index, obj2); 1948 } 1949 return found; 1950 } 1951 1952 /** 1953 * Rotates the elements in {@code list} by the distance {@code dist} 1954 * <p> 1955 * e.g. for a given list with elements [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], 1956 * calling rotate(list, 3) or rotate(list, -7) would modify the list to look 1957 * like this: [8, 9, 0, 1, 2, 3, 4, 5, 6, 7] 1958 * 1959 * @param lst 1960 * the list whose elements are to be rotated. 1961 * @param dist 1962 * is the distance the list is rotated. This can be any valid 1963 * integer. Negative values rotate the list backwards. 1964 */ 1965 @SuppressWarnings("unchecked") 1966 public static void rotate(List<?> lst, int dist) { 1967 List<Object> list = (List<Object>) lst; 1968 int size = list.size(); 1969 1970 // Can't sensibly rotate an empty collection 1971 if (size == 0) { 1972 return; 1973 } 1974 1975 // normalize the distance 1976 int normdist; 1977 if (dist > 0) { 1978 normdist = dist % size; 1979 } else { 1980 normdist = size - ((dist % size) * (-1)); 1981 } 1982 1983 if (normdist == 0 || normdist == size) { 1984 return; 1985 } 1986 1987 if (list instanceof RandomAccess) { 1988 // make sure each element gets juggled 1989 // with the element in the position it is supposed to go to 1990 Object temp = list.get(0); 1991 int index = 0, beginIndex = 0; 1992 for (int i = 0; i < size; i++) { 1993 index = (index + normdist) % size; 1994 temp = list.set(index, temp); 1995 if (index == beginIndex) { 1996 index = ++beginIndex; 1997 temp = list.get(beginIndex); 1998 } 1999 } 2000 } else { 2001 int divideIndex = (size - normdist) % size; 2002 List<Object> sublist1 = list.subList(0, divideIndex); 2003 List<Object> sublist2 = list.subList(divideIndex, size); 2004 reverse(sublist1); 2005 reverse(sublist2); 2006 reverse(list); 2007 } 2008 } 2009 2010 /** 2011 * Searches the {@code list} for {@code sublist} and returns the beginning 2012 * index of the first occurrence. 2013 * <p> 2014 * -1 is returned if the {@code sublist} does not exist in {@code list}. 2015 * 2016 * @param list 2017 * the List to search {@code sublist} in. 2018 * @param sublist 2019 * the List to search in {@code list}. 2020 * @return the beginning index of the first occurrence of {@code sublist} in 2021 * {@code list}, or -1. 2022 */ 2023 public static int indexOfSubList(List<?> list, List<?> sublist) { 2024 int size = list.size(); 2025 int sublistSize = sublist.size(); 2026 2027 if (sublistSize > size) { 2028 return -1; 2029 } 2030 2031 if (sublistSize == 0) { 2032 return 0; 2033 } 2034 2035 // find the first element of sublist in the list to get a head start 2036 Object firstObj = sublist.get(0); 2037 int index = list.indexOf(firstObj); 2038 if (index == -1) { 2039 return -1; 2040 } 2041 2042 while (index < size && (size - index >= sublistSize)) { 2043 ListIterator<?> listIt = list.listIterator(index); 2044 2045 if ((firstObj == null) ? listIt.next() == null : firstObj 2046 .equals(listIt.next())) { 2047 2048 // iterate through the elements in sublist to see 2049 // if they are included in the same order in the list 2050 ListIterator<?> sublistIt = sublist.listIterator(1); 2051 boolean difFound = false; 2052 while (sublistIt.hasNext()) { 2053 Object element = sublistIt.next(); 2054 if (!listIt.hasNext()) { 2055 return -1; 2056 } 2057 if ((element == null) ? listIt.next() != null : !element 2058 .equals(listIt.next())) { 2059 difFound = true; 2060 break; 2061 } 2062 } 2063 // All elements of sublist are found in main list 2064 // starting from index. 2065 if (!difFound) { 2066 return index; 2067 } 2068 } 2069 // This was not the sequence we were looking for, 2070 // continue search for the firstObj in main list 2071 // at the position after index. 2072 index++; 2073 } 2074 return -1; 2075 } 2076 2077 /** 2078 * Searches the {@code list} for {@code sublist} and returns the beginning 2079 * index of the last occurrence. 2080 * <p> 2081 * -1 is returned if the {@code sublist} does not exist in {@code list}. 2082 * 2083 * @param list 2084 * the list to search {@code sublist} in. 2085 * @param sublist 2086 * the list to search in {@code list}. 2087 * @return the beginning index of the last occurrence of {@code sublist} in 2088 * {@code list}, or -1. 2089 */ 2090 public static int lastIndexOfSubList(List<?> list, List<?> sublist) { 2091 int sublistSize = sublist.size(); 2092 int size = list.size(); 2093 2094 if (sublistSize > size) { 2095 return -1; 2096 } 2097 2098 if (sublistSize == 0) { 2099 return size; 2100 } 2101 2102 // find the last element of sublist in the list to get a head start 2103 Object lastObj = sublist.get(sublistSize - 1); 2104 int index = list.lastIndexOf(lastObj); 2105 2106 while ((index > -1) && (index + 1 >= sublistSize)) { 2107 ListIterator<?> listIt = list.listIterator(index + 1); 2108 2109 if ((lastObj == null) ? listIt.previous() == null : lastObj 2110 .equals(listIt.previous())) { 2111 // iterate through the elements in sublist to see 2112 // if they are included in the same order in the list 2113 ListIterator<?> sublistIt = sublist 2114 .listIterator(sublistSize - 1); 2115 boolean difFound = false; 2116 while (sublistIt.hasPrevious()) { 2117 Object element = sublistIt.previous(); 2118 if (!listIt.hasPrevious()) { 2119 return -1; 2120 } 2121 if ((element == null) ? listIt.previous() != null 2122 : !element.equals(listIt.previous())) { 2123 difFound = true; 2124 break; 2125 } 2126 } 2127 // All elements of sublist are found in main list 2128 // starting from listIt.nextIndex(). 2129 if (!difFound) { 2130 return listIt.nextIndex(); 2131 } 2132 } 2133 // This was not the sequence we were looking for, 2134 // continue search for the lastObj in main list 2135 // at the position before index. 2136 index--; 2137 } 2138 return -1; 2139 } 2140 2141 /** 2142 * Returns an {@code ArrayList} with all the elements in the {@code 2143 * enumeration}. The elements in the returned {@code ArrayList} are in the 2144 * same order as in the {@code enumeration}. 2145 * 2146 * @param enumeration 2147 * the source {@link Enumeration}. 2148 * @return an {@code ArrayList} from {@code enumeration}. 2149 */ 2150 public static <T> ArrayList<T> list(Enumeration<T> enumeration) { 2151 ArrayList<T> list = new ArrayList<T>(); 2152 while (enumeration.hasMoreElements()) { 2153 list.add(enumeration.nextElement()); 2154 } 2155 return list; 2156 } 2157 2158 /** 2159 * Returns a wrapper on the specified collection which synchronizes all 2160 * access to the collection. 2161 * 2162 * @param collection 2163 * the Collection to wrap in a synchronized collection. 2164 * @return a synchronized Collection. 2165 */ 2166 public static <T> Collection<T> synchronizedCollection( 2167 Collection<T> collection) { 2168 if (collection == null) { 2169 throw new NullPointerException("collection == null"); 2170 } 2171 return new SynchronizedCollection<T>(collection); 2172 } 2173 2174 /** 2175 * Returns a wrapper on the specified List which synchronizes all access to 2176 * the List. 2177 * 2178 * @param list 2179 * the List to wrap in a synchronized list. 2180 * @return a synchronized List. 2181 */ 2182 public static <T> List<T> synchronizedList(List<T> list) { 2183 if (list == null) { 2184 throw new NullPointerException("list == null"); 2185 } 2186 if (list instanceof RandomAccess) { 2187 return new SynchronizedRandomAccessList<T>(list); 2188 } 2189 return new SynchronizedList<T>(list); 2190 } 2191 2192 /** 2193 * Returns a wrapper on the specified map which synchronizes all access to 2194 * the map. 2195 * 2196 * @param map 2197 * the map to wrap in a synchronized map. 2198 * @return a synchronized Map. 2199 */ 2200 public static <K, V> Map<K, V> synchronizedMap(Map<K, V> map) { 2201 if (map == null) { 2202 throw new NullPointerException("map == null"); 2203 } 2204 return new SynchronizedMap<K, V>(map); 2205 } 2206 2207 /** 2208 * Returns a wrapper on the specified set which synchronizes all access to 2209 * the set. 2210 * 2211 * @param set 2212 * the set to wrap in a synchronized set. 2213 * @return a synchronized set. 2214 */ 2215 public static <E> Set<E> synchronizedSet(Set<E> set) { 2216 if (set == null) { 2217 throw new NullPointerException("set == null"); 2218 } 2219 return new SynchronizedSet<E>(set); 2220 } 2221 2222 /** 2223 * Returns a wrapper on the specified sorted map which synchronizes all 2224 * access to the sorted map. 2225 * 2226 * @param map 2227 * the sorted map to wrap in a synchronized sorted map. 2228 * @return a synchronized sorted map. 2229 */ 2230 public static <K, V> SortedMap<K, V> synchronizedSortedMap( 2231 SortedMap<K, V> map) { 2232 if (map == null) { 2233 throw new NullPointerException("map == null"); 2234 } 2235 return new SynchronizedSortedMap<K, V>(map); 2236 } 2237 2238 /** 2239 * Returns a wrapper on the specified sorted set which synchronizes all 2240 * access to the sorted set. 2241 * 2242 * @param set 2243 * the sorted set to wrap in a synchronized sorted set. 2244 * @return a synchronized sorted set. 2245 */ 2246 public static <E> SortedSet<E> synchronizedSortedSet(SortedSet<E> set) { 2247 if (set == null) { 2248 throw new NullPointerException("set == null"); 2249 } 2250 return new SynchronizedSortedSet<E>(set); 2251 } 2252 2253 /** 2254 * Returns a wrapper on the specified collection which throws an 2255 * {@code UnsupportedOperationException} whenever an attempt is made to 2256 * modify the collection. 2257 * 2258 * @param collection 2259 * the collection to wrap in an unmodifiable collection. 2260 * @return an unmodifiable collection. 2261 */ 2262 @SuppressWarnings("unchecked") 2263 public static <E> Collection<E> unmodifiableCollection( 2264 Collection<? extends E> collection) { 2265 if (collection == null) { 2266 throw new NullPointerException("collection == null"); 2267 } 2268 return new UnmodifiableCollection<E>((Collection<E>) collection); 2269 } 2270 2271 /** 2272 * Returns a wrapper on the specified list which throws an 2273 * {@code UnsupportedOperationException} whenever an attempt is made to 2274 * modify the list. 2275 * 2276 * @param list 2277 * the list to wrap in an unmodifiable list. 2278 * @return an unmodifiable List. 2279 */ 2280 @SuppressWarnings("unchecked") 2281 public static <E> List<E> unmodifiableList(List<? extends E> list) { 2282 if (list == null) { 2283 throw new NullPointerException("list == null"); 2284 } 2285 if (list instanceof RandomAccess) { 2286 return new UnmodifiableRandomAccessList<E>((List<E>) list); 2287 } 2288 return new UnmodifiableList<E>((List<E>) list); 2289 } 2290 2291 /** 2292 * Returns a wrapper on the specified map which throws an 2293 * {@code UnsupportedOperationException} whenever an attempt is made to 2294 * modify the map. 2295 * 2296 * @param map 2297 * the map to wrap in an unmodifiable map. 2298 * @return a unmodifiable map. 2299 */ 2300 @SuppressWarnings("unchecked") 2301 public static <K, V> Map<K, V> unmodifiableMap( 2302 Map<? extends K, ? extends V> map) { 2303 if (map == null) { 2304 throw new NullPointerException("map == null"); 2305 } 2306 return new UnmodifiableMap<K, V>((Map<K, V>) map); 2307 } 2308 2309 /** 2310 * Returns a wrapper on the specified set which throws an 2311 * {@code UnsupportedOperationException} whenever an attempt is made to 2312 * modify the set. 2313 * 2314 * @param set 2315 * the set to wrap in an unmodifiable set. 2316 * @return a unmodifiable set 2317 */ 2318 @SuppressWarnings("unchecked") 2319 public static <E> Set<E> unmodifiableSet(Set<? extends E> set) { 2320 if (set == null) { 2321 throw new NullPointerException("set == null"); 2322 } 2323 return new UnmodifiableSet<E>((Set<E>) set); 2324 } 2325 2326 /** 2327 * Returns a wrapper on the specified sorted map which throws an 2328 * {@code UnsupportedOperationException} whenever an attempt is made to 2329 * modify the sorted map. 2330 * 2331 * @param map 2332 * the sorted map to wrap in an unmodifiable sorted map. 2333 * @return a unmodifiable sorted map 2334 */ 2335 @SuppressWarnings("unchecked") 2336 public static <K, V> SortedMap<K, V> unmodifiableSortedMap( 2337 SortedMap<K, ? extends V> map) { 2338 if (map == null) { 2339 throw new NullPointerException("map == null"); 2340 } 2341 return new UnmodifiableSortedMap<K, V>((SortedMap<K, V>) map); 2342 } 2343 2344 /** 2345 * Returns a wrapper on the specified sorted set which throws an 2346 * {@code UnsupportedOperationException} whenever an attempt is made to 2347 * modify the sorted set. 2348 * 2349 * @param set 2350 * the sorted set to wrap in an unmodifiable sorted set. 2351 * @return a unmodifiable sorted set. 2352 */ 2353 public static <E> SortedSet<E> unmodifiableSortedSet(SortedSet<E> set) { 2354 if (set == null) { 2355 throw new NullPointerException("set == null"); 2356 } 2357 return new UnmodifiableSortedSet<E>(set); 2358 } 2359 2360 /** 2361 * Returns the number of elements in the {@code Collection} that match the 2362 * {@code Object} passed. If the {@code Object} is {@code null}, then the 2363 * number of {@code null} elements is returned. 2364 * 2365 * @param c 2366 * the {@code Collection} to search. 2367 * @param o 2368 * the {@code Object} to search for. 2369 * @return the number of matching elements. 2370 * @throws NullPointerException 2371 * if the {@code Collection} parameter is {@code null}. 2372 * @since 1.5 2373 */ 2374 public static int frequency(Collection<?> c, Object o) { 2375 if (c == null) { 2376 throw new NullPointerException("c == null"); 2377 } 2378 if (c.isEmpty()) { 2379 return 0; 2380 } 2381 int result = 0; 2382 Iterator<?> itr = c.iterator(); 2383 while (itr.hasNext()) { 2384 Object e = itr.next(); 2385 if (o == null ? e == null : o.equals(e)) { 2386 result++; 2387 } 2388 } 2389 return result; 2390 } 2391 2392 /** 2393 * Returns a type-safe empty, immutable {@link List}. 2394 * 2395 * @return an empty {@link List}. 2396 * @since 1.5 2397 * @see #EMPTY_LIST 2398 */ 2399 @SuppressWarnings("unchecked") 2400 public static final <T> List<T> emptyList() { 2401 return EMPTY_LIST; 2402 } 2403 2404 /** 2405 * Returns a type-safe empty, immutable {@link Set}. 2406 * 2407 * @return an empty {@link Set}. 2408 * @since 1.5 2409 * @see #EMPTY_SET 2410 */ 2411 @SuppressWarnings("unchecked") 2412 public static final <T> Set<T> emptySet() { 2413 return EMPTY_SET; 2414 } 2415 2416 /** 2417 * Returns a type-safe empty, immutable {@link Map}. 2418 * 2419 * @return an empty {@link Map}. 2420 * @since 1.5 2421 * @see #EMPTY_MAP 2422 */ 2423 @SuppressWarnings("unchecked") 2424 public static final <K, V> Map<K, V> emptyMap() { 2425 return EMPTY_MAP; 2426 } 2427 2428 /** 2429 * Returns an enumeration containing no elements. 2430 * @since 1.7 2431 */ 2432 @SuppressWarnings("unchecked") 2433 public static <T> Enumeration<T> emptyEnumeration() { 2434 return (Enumeration<T>) EMPTY_ENUMERATION; 2435 } 2436 2437 /** 2438 * Returns an iterator containing no elements. 2439 * @since 1.7 2440 */ 2441 @SuppressWarnings("unchecked") 2442 public static <T> Iterator<T> emptyIterator() { 2443 return (Iterator<T>) EMPTY_ITERATOR; 2444 } 2445 2446 /** 2447 * Returns a list iterator containing no elements. 2448 * @since 1.7 2449 */ 2450 public static <T> ListIterator<T> emptyListIterator() { 2451 return Collections.<T>emptyList().listIterator(); 2452 } 2453 2454 /** 2455 * Returns a dynamically typesafe view of the specified collection. Trying 2456 * to insert an element of the wrong type into this collection throws a 2457 * {@code ClassCastException}. At creation time the types in {@code c} are 2458 * not checked for correct type. 2459 * 2460 * @param c 2461 * the collection to be wrapped in a typesafe collection. 2462 * @param type 2463 * the type of the elements permitted to insert. 2464 * @return a typesafe collection. 2465 */ 2466 public static <E> Collection<E> checkedCollection(Collection<E> c, 2467 Class<E> type) { 2468 return new CheckedCollection<E>(c, type); 2469 } 2470 2471 /** 2472 * Returns a dynamically typesafe view of the specified map. Trying to 2473 * insert an element of the wrong type into this map throws a 2474 * {@code ClassCastException}. At creation time the types in {@code m} are 2475 * not checked for correct type. 2476 * 2477 * @param m 2478 * the map to be wrapped in a typesafe map. 2479 * @param keyType 2480 * the type of the keys permitted to insert. 2481 * @param valueType 2482 * the type of the values permitted to insert. 2483 * @return a typesafe map. 2484 */ 2485 public static <K, V> Map<K, V> checkedMap(Map<K, V> m, Class<K> keyType, 2486 Class<V> valueType) { 2487 return new CheckedMap<K, V>(m, keyType, valueType); 2488 } 2489 2490 /** 2491 * Returns a dynamically typesafe view of the specified list. Trying to 2492 * insert an element of the wrong type into this list throws a 2493 * {@code ClassCastException}. At creation time the types in {@code list} 2494 * are not checked for correct type. 2495 * 2496 * @param list 2497 * the list to be wrapped in a typesafe list. 2498 * @param type 2499 * the type of the elements permitted to insert. 2500 * @return a typesafe list. 2501 */ 2502 public static <E> List<E> checkedList(List<E> list, Class<E> type) { 2503 if (list instanceof RandomAccess) { 2504 return new CheckedRandomAccessList<E>(list, type); 2505 } 2506 return new CheckedList<E>(list, type); 2507 } 2508 2509 /** 2510 * Returns a dynamically typesafe view of the specified set. Trying to 2511 * insert an element of the wrong type into this set throws a 2512 * {@code ClassCastException}. At creation time the types in {@code s} are 2513 * not checked for correct type. 2514 * 2515 * @param s 2516 * the set to be wrapped in a typesafe set. 2517 * @param type 2518 * the type of the elements permitted to insert. 2519 * @return a typesafe set. 2520 */ 2521 public static <E> Set<E> checkedSet(Set<E> s, Class<E> type) { 2522 return new CheckedSet<E>(s, type); 2523 } 2524 2525 /** 2526 * Returns a dynamically typesafe view of the specified sorted map. Trying 2527 * to insert an element of the wrong type into this sorted map throws a 2528 * {@code ClassCastException}. At creation time the types in {@code m} are 2529 * not checked for correct type. 2530 * 2531 * @param m 2532 * the sorted map to be wrapped in a typesafe sorted map. 2533 * @param keyType 2534 * the type of the keys permitted to insert. 2535 * @param valueType 2536 * the type of the values permitted to insert. 2537 * @return a typesafe sorted map. 2538 */ 2539 public static <K, V> SortedMap<K, V> checkedSortedMap(SortedMap<K, V> m, 2540 Class<K> keyType, Class<V> valueType) { 2541 return new CheckedSortedMap<K, V>(m, keyType, valueType); 2542 } 2543 2544 /** 2545 * Returns a dynamically typesafe view of the specified sorted set. Trying 2546 * to insert an element of the wrong type into this sorted set throws a 2547 * {@code ClassCastException}. At creation time the types in {@code s} are 2548 * not checked for correct type. 2549 * 2550 * @param s 2551 * the sorted set to be wrapped in a typesafe sorted set. 2552 * @param type 2553 * the type of the elements permitted to insert. 2554 * @return a typesafe sorted set. 2555 */ 2556 public static <E> SortedSet<E> checkedSortedSet(SortedSet<E> s, 2557 Class<E> type) { 2558 return new CheckedSortedSet<E>(s, type); 2559 } 2560 2561 /** 2562 * Adds all the specified elements to the specified collection. 2563 * 2564 * @param c 2565 * the collection the elements are to be inserted into. 2566 * @param a 2567 * the elements to insert. 2568 * @return true if the collection changed during insertion. 2569 * @throws UnsupportedOperationException 2570 * when the method is not supported. 2571 * @throws NullPointerException 2572 * when {@code c} or {@code a} is {@code null}, or {@code a} 2573 * contains one or more {@code null} elements and {@code c} 2574 * doesn't support {@code null} elements. 2575 * @throws IllegalArgumentException 2576 * if at least one of the elements can't be inserted into the 2577 * collection. 2578 */ 2579 @SafeVarargs 2580 public static <T> boolean addAll(Collection<? super T> c, T... a) { 2581 boolean modified = false; 2582 for (int i = 0; i < a.length; i++) { 2583 modified |= c.add(a[i]); 2584 } 2585 return modified; 2586 } 2587 2588 /** 2589 * Returns whether the specified collections have no elements in common. 2590 * 2591 * @param c1 2592 * the first collection. 2593 * @param c2 2594 * the second collection. 2595 * @return {@code true} if the collections have no elements in common, 2596 * {@code false} otherwise. 2597 * @throws NullPointerException 2598 * if one of the collections is {@code null}. 2599 */ 2600 public static boolean disjoint(Collection<?> c1, Collection<?> c2) { 2601 if ((c1 instanceof Set) && !(c2 instanceof Set) 2602 || (c2.size()) > c1.size()) { 2603 Collection<?> tmp = c1; 2604 c1 = c2; 2605 c2 = tmp; 2606 } 2607 Iterator<?> it = c1.iterator(); 2608 while (it.hasNext()) { 2609 if (c2.contains(it.next())) { 2610 return false; 2611 } 2612 } 2613 return true; 2614 } 2615 2616 /** 2617 * Checks if specified object is instance of specified class. Used for a 2618 * dynamically typesafe view of the collections. 2619 * 2620 * @param obj - 2621 * object is to be checked 2622 * @param type - 2623 * class of object that should be 2624 * @return specified object 2625 */ 2626 static <E> E checkType(E obj, Class<? extends E> type) { 2627 if (obj != null && !type.isInstance(obj)) { 2628 throw new ClassCastException("Attempt to insert element of type " + obj.getClass() + 2629 " into collection of type " + type); 2630 } 2631 return obj; 2632 } 2633 2634 /** 2635 * Returns a set backed by {@code map}. 2636 * 2637 * @throws IllegalArgumentException if the map is not empty 2638 * @since 1.6 2639 */ 2640 public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) { 2641 if (map.isEmpty()) { 2642 return new SetFromMap<E>(map); 2643 } 2644 throw new IllegalArgumentException("map not empty"); 2645 } 2646 2647 /** 2648 * Returns a last-in, first-out queue as a view of {@code deque}. 2649 * 2650 * @since 1.6 2651 */ 2652 public static <T> Queue<T> asLifoQueue(Deque<T> deque) { 2653 return new AsLIFOQueue<T>(deque); 2654 } 2655 2656 private static class SetFromMap<E> extends AbstractSet<E> implements Serializable { 2657 private static final long serialVersionUID = 2454657854757543876L; 2658 2659 // Must be named as is, to pass serialization compatibility test. 2660 private final Map<E, Boolean> m; 2661 2662 private transient Set<E> backingSet; 2663 2664 SetFromMap(final Map<E, Boolean> map) { 2665 m = map; 2666 backingSet = map.keySet(); 2667 } 2668 2669 @Override public boolean equals(Object object) { 2670 return backingSet.equals(object); 2671 } 2672 2673 @Override public int hashCode() { 2674 return backingSet.hashCode(); 2675 } 2676 2677 @Override public boolean add(E object) { 2678 return m.put(object, Boolean.TRUE) == null; 2679 } 2680 2681 @Override public void clear() { 2682 m.clear(); 2683 } 2684 2685 @Override public String toString() { 2686 return backingSet.toString(); 2687 } 2688 2689 @Override public boolean contains(Object object) { 2690 return backingSet.contains(object); 2691 } 2692 2693 @Override public boolean containsAll(Collection<?> collection) { 2694 return backingSet.containsAll(collection); 2695 } 2696 2697 @Override public boolean isEmpty() { 2698 return m.isEmpty(); 2699 } 2700 2701 @Override public boolean remove(Object object) { 2702 return m.remove(object) != null; 2703 } 2704 2705 @Override public boolean retainAll(Collection<?> collection) { 2706 return backingSet.retainAll(collection); 2707 } 2708 2709 @Override public Object[] toArray() { 2710 return backingSet.toArray(); 2711 } 2712 2713 @Override 2714 public <T> T[] toArray(T[] contents) { 2715 return backingSet.toArray(contents); 2716 } 2717 2718 @Override public Iterator<E> iterator() { 2719 return backingSet.iterator(); 2720 } 2721 2722 @Override public int size() { 2723 return m.size(); 2724 } 2725 2726 @SuppressWarnings("unchecked") 2727 private void readObject(ObjectInputStream stream) 2728 throws IOException, ClassNotFoundException { 2729 stream.defaultReadObject(); 2730 backingSet = m.keySet(); 2731 } 2732 } 2733 2734 private static class AsLIFOQueue<E> extends AbstractQueue<E> implements Serializable { 2735 private static final long serialVersionUID = 1802017725587941708L; 2736 2737 // Must be named as is, to pass serialization compatibility test. 2738 private final Deque<E> q; 2739 2740 AsLIFOQueue(final Deque<E> deque) { 2741 this.q = deque; 2742 } 2743 2744 @Override public Iterator<E> iterator() { 2745 return q.iterator(); 2746 } 2747 2748 @Override public int size() { 2749 return q.size(); 2750 } 2751 2752 @Override public boolean offer(E o) { 2753 return q.offerFirst(o); 2754 } 2755 2756 @Override public E peek() { 2757 return q.peekFirst(); 2758 } 2759 2760 @Override public E poll() { 2761 return q.pollFirst(); 2762 } 2763 2764 @Override public boolean add(E o) { 2765 q.push(o); 2766 return true; 2767 } 2768 2769 @Override public void clear() { 2770 q.clear(); 2771 } 2772 2773 @Override public E element() { 2774 return q.getFirst(); 2775 } 2776 2777 @Override public E remove() { 2778 return q.pop(); 2779 } 2780 2781 @Override public boolean contains(Object object) { 2782 return q.contains(object); 2783 } 2784 2785 @Override public boolean containsAll(Collection<?> collection) { 2786 return q.containsAll(collection); 2787 } 2788 2789 @Override public boolean isEmpty() { 2790 return q.isEmpty(); 2791 } 2792 2793 @Override public boolean remove(Object object) { 2794 return q.remove(object); 2795 } 2796 2797 @Override public boolean removeAll(Collection<?> collection) { 2798 return q.removeAll(collection); 2799 } 2800 2801 @Override public boolean retainAll(Collection<?> collection) { 2802 return q.retainAll(collection); 2803 } 2804 2805 @Override public Object[] toArray() { 2806 return q.toArray(); 2807 } 2808 2809 @Override public <T> T[] toArray(T[] contents) { 2810 return q.toArray(contents); 2811 } 2812 2813 @Override public String toString() { 2814 return q.toString(); 2815 } 2816 } 2817 2818 /** 2819 * A dynamically typesafe view of a Collection. 2820 */ 2821 private static class CheckedCollection<E> implements Collection<E>, Serializable { 2822 2823 private static final long serialVersionUID = 1578914078182001775L; 2824 2825 final Collection<E> c; 2826 2827 final Class<E> type; 2828 2829 public CheckedCollection(Collection<E> c, Class<E> type) { 2830 if (c == null) { 2831 throw new NullPointerException("c == null"); 2832 } else if (type == null) { 2833 throw new NullPointerException("type == null"); 2834 } 2835 this.c = c; 2836 this.type = type; 2837 } 2838 2839 @Override public int size() { 2840 return c.size(); 2841 } 2842 2843 @Override public boolean isEmpty() { 2844 return c.isEmpty(); 2845 } 2846 2847 @Override public boolean contains(Object obj) { 2848 return c.contains(obj); 2849 } 2850 2851 @Override public Iterator<E> iterator() { 2852 Iterator<E> i = c.iterator(); 2853 if (i instanceof ListIterator) { 2854 i = new CheckedListIterator<E>((ListIterator<E>) i, type); 2855 } 2856 return i; 2857 } 2858 2859 @Override public Object[] toArray() { 2860 return c.toArray(); 2861 } 2862 2863 @Override public <T> T[] toArray(T[] arr) { 2864 return c.toArray(arr); 2865 } 2866 2867 @Override public boolean add(E obj) { 2868 return c.add(checkType(obj, type)); 2869 } 2870 2871 @Override public boolean remove(Object obj) { 2872 return c.remove(obj); 2873 } 2874 2875 @Override public boolean containsAll(Collection<?> c1) { 2876 return c.containsAll(c1); 2877 } 2878 2879 @SuppressWarnings("unchecked") 2880 @Override public boolean addAll(Collection<? extends E> c1) { 2881 Object[] array = c1.toArray(); 2882 for (Object o : array) { 2883 checkType(o, type); 2884 } 2885 return c.addAll((List<E>) Arrays.asList(array)); 2886 } 2887 2888 @Override public boolean removeAll(Collection<?> c1) { 2889 return c.removeAll(c1); 2890 } 2891 2892 @Override public boolean retainAll(Collection<?> c1) { 2893 return c.retainAll(c1); 2894 } 2895 2896 @Override public void clear() { 2897 c.clear(); 2898 } 2899 2900 @Override public String toString() { 2901 return c.toString(); 2902 } 2903 } 2904 2905 /** 2906 * Class represents a dynamically typesafe view of the specified 2907 * ListIterator. 2908 */ 2909 private static class CheckedListIterator<E> implements ListIterator<E> { 2910 2911 private final ListIterator<E> i; 2912 2913 private final Class<E> type; 2914 2915 /** 2916 * Constructs a dynamically typesafe view of the specified ListIterator. 2917 * 2918 * @param i - 2919 * the listIterator for which a dynamically typesafe view to 2920 * be constructed. 2921 */ 2922 public CheckedListIterator(ListIterator<E> i, Class<E> type) { 2923 this.i = i; 2924 this.type = type; 2925 } 2926 2927 @Override public boolean hasNext() { 2928 return i.hasNext(); 2929 } 2930 2931 @Override public E next() { 2932 return i.next(); 2933 } 2934 2935 @Override public void remove() { 2936 i.remove(); 2937 } 2938 2939 @Override public boolean hasPrevious() { 2940 return i.hasPrevious(); 2941 } 2942 2943 @Override public E previous() { 2944 return i.previous(); 2945 } 2946 2947 @Override public int nextIndex() { 2948 return i.nextIndex(); 2949 } 2950 2951 @Override public int previousIndex() { 2952 return i.previousIndex(); 2953 } 2954 2955 @Override public void set(E obj) { 2956 i.set(checkType(obj, type)); 2957 } 2958 2959 @Override public void add(E obj) { 2960 i.add(checkType(obj, type)); 2961 } 2962 } 2963 2964 /** 2965 * Class represents a dynamically typesafe view of a List. 2966 */ 2967 private static class CheckedList<E> extends CheckedCollection<E> implements List<E> { 2968 2969 private static final long serialVersionUID = 65247728283967356L; 2970 2971 final List<E> l; 2972 2973 public CheckedList(List<E> l, Class<E> type) { 2974 super(l, type); 2975 this.l = l; 2976 } 2977 2978 @SuppressWarnings("unchecked") 2979 @Override public boolean addAll(int index, Collection<? extends E> c1) { 2980 Object[] array = c1.toArray(); 2981 for (Object o : array) { 2982 checkType(o, type); 2983 } 2984 return l.addAll(index, (List<E>) Arrays.asList(array)); 2985 } 2986 2987 @Override public E get(int index) { 2988 return l.get(index); 2989 } 2990 2991 @Override public E set(int index, E obj) { 2992 return l.set(index, checkType(obj, type)); 2993 } 2994 2995 @Override public void add(int index, E obj) { 2996 l.add(index, checkType(obj, type)); 2997 } 2998 2999 @Override public E remove(int index) { 3000 return l.remove(index); 3001 } 3002 3003 @Override public int indexOf(Object obj) { 3004 return l.indexOf(obj); 3005 } 3006 3007 @Override public int lastIndexOf(Object obj) { 3008 return l.lastIndexOf(obj); 3009 } 3010 3011 @Override public ListIterator<E> listIterator() { 3012 return new CheckedListIterator<E>(l.listIterator(), type); 3013 } 3014 3015 @Override public ListIterator<E> listIterator(int index) { 3016 return new CheckedListIterator<E>(l.listIterator(index), type); 3017 } 3018 3019 @Override public List<E> subList(int fromIndex, int toIndex) { 3020 return checkedList(l.subList(fromIndex, toIndex), type); 3021 } 3022 3023 @Override public boolean equals(Object obj) { 3024 return l.equals(obj); 3025 } 3026 3027 @Override public int hashCode() { 3028 return l.hashCode(); 3029 } 3030 } 3031 3032 /** 3033 * A dynamically typesafe view of a RandomAccessList. 3034 */ 3035 private static class CheckedRandomAccessList<E> extends CheckedList<E> implements RandomAccess { 3036 3037 private static final long serialVersionUID = 1638200125423088369L; 3038 3039 public CheckedRandomAccessList(List<E> l, Class<E> type) { 3040 super(l, type); 3041 } 3042 } 3043 3044 /** 3045 * A dynamically typesafe view of a Set. 3046 */ 3047 private static class CheckedSet<E> extends CheckedCollection<E> implements Set<E> { 3048 3049 private static final long serialVersionUID = 4694047833775013803L; 3050 3051 public CheckedSet(Set<E> s, Class<E> type) { 3052 super(s, type); 3053 } 3054 3055 @Override public boolean equals(Object obj) { 3056 return c.equals(obj); 3057 } 3058 3059 @Override public int hashCode() { 3060 return c.hashCode(); 3061 } 3062 3063 } 3064 3065 /** 3066 * A dynamically typesafe view of a Map. 3067 */ 3068 private static class CheckedMap<K, V> implements Map<K, V>, Serializable { 3069 3070 private static final long serialVersionUID = 5742860141034234728L; 3071 3072 final Map<K, V> m; 3073 final Class<K> keyType; 3074 final Class<V> valueType; 3075 3076 private CheckedMap(Map<K, V> m, Class<K> keyType, Class<V> valueType) { 3077 if (m == null) { 3078 throw new NullPointerException("m == null"); 3079 } else if (keyType == null) { 3080 throw new NullPointerException("keyType == null"); 3081 } else if (valueType == null) { 3082 throw new NullPointerException("valueType == null"); 3083 } 3084 this.m = m; 3085 this.keyType = keyType; 3086 this.valueType = valueType; 3087 } 3088 3089 @Override public int size() { 3090 return m.size(); 3091 } 3092 3093 @Override public boolean isEmpty() { 3094 return m.isEmpty(); 3095 } 3096 3097 @Override public boolean containsKey(Object key) { 3098 return m.containsKey(key); 3099 } 3100 3101 @Override public boolean containsValue(Object value) { 3102 return m.containsValue(value); 3103 } 3104 3105 @Override public V get(Object key) { 3106 return m.get(key); 3107 } 3108 3109 @Override public V put(K key, V value) { 3110 return m.put(checkType(key, keyType), checkType(value, valueType)); 3111 } 3112 3113 @Override public V remove(Object key) { 3114 return m.remove(key); 3115 } 3116 3117 @SuppressWarnings("unchecked") 3118 @Override public void putAll(Map<? extends K, ? extends V> map) { 3119 int size = map.size(); 3120 if (size == 0) { 3121 return; 3122 } 3123 Map.Entry<? extends K, ? extends V>[] entries = new Map.Entry[size]; 3124 Iterator<? extends Map.Entry<? extends K, ? extends V>> it = map 3125 .entrySet().iterator(); 3126 for (int i = 0; i < size; i++) { 3127 Map.Entry<? extends K, ? extends V> e = it.next(); 3128 checkType(e.getKey(), keyType); 3129 checkType(e.getValue(), valueType); 3130 entries[i] = e; 3131 } 3132 for (int i = 0; i < size; i++) { 3133 m.put(entries[i].getKey(), entries[i].getValue()); 3134 } 3135 } 3136 3137 @Override public void clear() { 3138 m.clear(); 3139 } 3140 3141 @Override public Set<K> keySet() { 3142 return m.keySet(); 3143 } 3144 3145 @Override public Collection<V> values() { 3146 return m.values(); 3147 } 3148 3149 @Override public Set<Map.Entry<K, V>> entrySet() { 3150 return new CheckedEntrySet<K, V>(m.entrySet(), valueType); 3151 } 3152 3153 @Override public boolean equals(Object obj) { 3154 return m.equals(obj); 3155 } 3156 3157 @Override public int hashCode() { 3158 return m.hashCode(); 3159 } 3160 3161 @Override public String toString() { 3162 return m.toString(); 3163 } 3164 3165 /** 3166 * A dynamically typesafe view of a Map.Entry. 3167 */ 3168 private static class CheckedEntry<K, V> implements Map.Entry<K, V> { 3169 final Map.Entry<K, V> e; 3170 final Class<V> valueType; 3171 3172 public CheckedEntry(Map.Entry<K, V> e, Class<V> valueType) { 3173 if (e == null) { 3174 throw new NullPointerException("e == null"); 3175 } 3176 this.e = e; 3177 this.valueType = valueType; 3178 } 3179 3180 @Override public K getKey() { 3181 return e.getKey(); 3182 } 3183 3184 @Override public V getValue() { 3185 return e.getValue(); 3186 } 3187 3188 @Override public V setValue(V obj) { 3189 return e.setValue(checkType(obj, valueType)); 3190 } 3191 3192 @Override public boolean equals(Object obj) { 3193 return e.equals(obj); 3194 } 3195 3196 @Override public int hashCode() { 3197 return e.hashCode(); 3198 } 3199 } 3200 3201 /** 3202 * A dynamically typesafe view of an entry set. 3203 */ 3204 private static class CheckedEntrySet<K, V> implements Set<Map.Entry<K, V>> { 3205 final Set<Map.Entry<K, V>> s; 3206 final Class<V> valueType; 3207 3208 public CheckedEntrySet(Set<Map.Entry<K, V>> s, Class<V> valueType) { 3209 this.s = s; 3210 this.valueType = valueType; 3211 } 3212 3213 @Override public Iterator<Map.Entry<K, V>> iterator() { 3214 return new CheckedEntryIterator<K, V>(s.iterator(), valueType); 3215 } 3216 3217 @Override public Object[] toArray() { 3218 int thisSize = size(); 3219 Object[] array = new Object[thisSize]; 3220 Iterator<?> it = iterator(); 3221 for (int i = 0; i < thisSize; i++) { 3222 array[i] = it.next(); 3223 } 3224 return array; 3225 } 3226 3227 @SuppressWarnings("unchecked") 3228 @Override public <T> T[] toArray(T[] array) { 3229 int thisSize = size(); 3230 if (array.length < thisSize) { 3231 Class<?> ct = array.getClass().getComponentType(); 3232 array = (T[]) Array.newInstance(ct, thisSize); 3233 } 3234 Iterator<?> it = iterator(); 3235 for (int i = 0; i < thisSize; i++) { 3236 array[i] = (T) it.next(); 3237 } 3238 if (thisSize < array.length) { 3239 array[thisSize] = null; 3240 } 3241 return array; 3242 } 3243 3244 @Override public boolean retainAll(Collection<?> c) { 3245 return s.retainAll(c); 3246 } 3247 3248 @Override public boolean removeAll(Collection<?> c) { 3249 return s.removeAll(c); 3250 } 3251 3252 @Override public boolean containsAll(Collection<?> c) { 3253 return s.containsAll(c); 3254 } 3255 3256 @Override public boolean addAll(Collection<? extends Map.Entry<K, V>> c) { 3257 throw new UnsupportedOperationException(); 3258 } 3259 3260 @Override public boolean remove(Object o) { 3261 return s.remove(o); 3262 } 3263 3264 @Override public boolean contains(Object o) { 3265 return s.contains(o); 3266 } 3267 3268 @Override public boolean add(Map.Entry<K, V> o) { 3269 throw new UnsupportedOperationException(); 3270 } 3271 3272 @Override public boolean isEmpty() { 3273 return s.isEmpty(); 3274 } 3275 3276 @Override public void clear() { 3277 s.clear(); 3278 } 3279 3280 @Override public int size() { 3281 return s.size(); 3282 } 3283 3284 @Override public int hashCode() { 3285 return s.hashCode(); 3286 } 3287 3288 @Override public boolean equals(Object object) { 3289 return s.equals(object); 3290 } 3291 3292 /** 3293 * A dynamically typesafe view of an entry iterator. 3294 */ 3295 private static class CheckedEntryIterator<K, V> implements Iterator<Map.Entry<K, V>> { 3296 Iterator<Map.Entry<K, V>> i; 3297 Class<V> valueType; 3298 3299 public CheckedEntryIterator(Iterator<Map.Entry<K, V>> i, 3300 Class<V> valueType) { 3301 this.i = i; 3302 this.valueType = valueType; 3303 } 3304 3305 @Override public boolean hasNext() { 3306 return i.hasNext(); 3307 } 3308 3309 @Override public void remove() { 3310 i.remove(); 3311 } 3312 3313 @Override public Map.Entry<K, V> next() { 3314 return new CheckedEntry<K, V>(i.next(), valueType); 3315 } 3316 } 3317 } 3318 } 3319 3320 /** 3321 * A dynamically typesafe view of a SortedSet. 3322 */ 3323 private static class CheckedSortedSet<E> extends CheckedSet<E> implements SortedSet<E> { 3324 private static final long serialVersionUID = 1599911165492914959L; 3325 private final SortedSet<E> ss; 3326 3327 public CheckedSortedSet(SortedSet<E> s, Class<E> type) { 3328 super(s, type); 3329 this.ss = s; 3330 } 3331 3332 @Override public Comparator<? super E> comparator() { 3333 return ss.comparator(); 3334 } 3335 3336 @Override public SortedSet<E> subSet(E fromElement, E toElement) { 3337 return new CheckedSortedSet<E>(ss.subSet(fromElement, toElement), 3338 type); 3339 } 3340 3341 @Override public SortedSet<E> headSet(E toElement) { 3342 return new CheckedSortedSet<E>(ss.headSet(toElement), type); 3343 } 3344 3345 @Override public SortedSet<E> tailSet(E fromElement) { 3346 return new CheckedSortedSet<E>(ss.tailSet(fromElement), type); 3347 } 3348 3349 @Override public E first() { 3350 return ss.first(); 3351 } 3352 3353 @Override public E last() { 3354 return ss.last(); 3355 } 3356 } 3357 3358 /** 3359 * A dynamically typesafe view of a SortedMap. 3360 */ 3361 private static class CheckedSortedMap<K, V> extends CheckedMap<K, V> 3362 implements SortedMap<K, V> { 3363 private static final long serialVersionUID = 1599671320688067438L; 3364 final SortedMap<K, V> sm; 3365 3366 CheckedSortedMap(SortedMap<K, V> m, Class<K> keyType, Class<V> valueType) { 3367 super(m, keyType, valueType); 3368 this.sm = m; 3369 } 3370 3371 @Override public Comparator<? super K> comparator() { 3372 return sm.comparator(); 3373 } 3374 3375 @Override public SortedMap<K, V> subMap(K fromKey, K toKey) { 3376 return new CheckedSortedMap<K, V>(sm.subMap(fromKey, toKey), keyType, valueType); 3377 } 3378 3379 @Override public SortedMap<K, V> headMap(K toKey) { 3380 return new CheckedSortedMap<K, V>(sm.headMap(toKey), keyType, valueType); 3381 } 3382 3383 @Override public SortedMap<K, V> tailMap(K fromKey) { 3384 return new CheckedSortedMap<K, V>(sm.tailMap(fromKey), keyType, valueType); 3385 } 3386 3387 @Override public K firstKey() { 3388 return sm.firstKey(); 3389 } 3390 3391 @Override public K lastKey() { 3392 return sm.lastKey(); 3393 } 3394 } 3395 3396 /** 3397 * Computes a hash code and applies a supplemental hash function to defend 3398 * against poor quality hash functions. This is critical because HashMap 3399 * uses power-of-two length hash tables, that otherwise encounter collisions 3400 * for hash codes that do not differ in lower or upper bits. 3401 * Routine taken from java.util.concurrent.ConcurrentHashMap.hash(int). 3402 * @hide 3403 */ 3404 public static int secondaryHash(Object key) { 3405 return secondaryHash(key.hashCode()); 3406 } 3407 3408 /** 3409 * Computes an identity hash code and applies a supplemental hash function to defend 3410 * against poor quality hash functions. This is critical because identity hash codes 3411 * are currently implemented as object addresses, which will have been aligned by the 3412 * underlying memory allocator causing all hash codes to have the same bottom bits. 3413 * @hide 3414 */ 3415 public static int secondaryIdentityHash(Object key) { 3416 return secondaryHash(System.identityHashCode(key)); 3417 } 3418 3419 private static int secondaryHash(int h) { 3420 // Spread bits to regularize both segment and index locations, 3421 // using variant of single-word Wang/Jenkins hash. 3422 h += (h << 15) ^ 0xffffcd7d; 3423 h ^= (h >>> 10); 3424 h += (h << 3); 3425 h ^= (h >>> 6); 3426 h += (h << 2) + (h << 14); 3427 return h ^ (h >>> 16); 3428 } 3429 3430 /** 3431 * Returns the smallest power of two >= its argument, with several caveats: 3432 * If the argument is negative but not Integer.MIN_VALUE, the method returns 3433 * zero. If the argument is > 2^30 or equal to Integer.MIN_VALUE, the method 3434 * returns Integer.MIN_VALUE. If the argument is zero, the method returns 3435 * zero. 3436 * @hide 3437 */ 3438 public static int roundUpToPowerOfTwo(int i) { 3439 i--; // If input is a power of two, shift its high-order bit right. 3440 3441 // "Smear" the high-order bit all the way to the right. 3442 i |= i >>> 1; 3443 i |= i >>> 2; 3444 i |= i >>> 4; 3445 i |= i >>> 8; 3446 i |= i >>> 16; 3447 3448 return i + 1; 3449 } 3450} 3451