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