< prev index next >

src/java.base/share/classes/java/util/ImmutableCollections.java

Print this page




  78         @Override public boolean addAll(Collection<? extends E> c) { throw uoe(); }
  79         @Override public void    clear() { throw uoe(); }
  80         @Override public boolean remove(Object o) { throw uoe(); }
  81         @Override public boolean removeAll(Collection<?> c) { throw uoe(); }
  82         @Override public boolean removeIf(Predicate<? super E> filter) { throw uoe(); }
  83         @Override public boolean retainAll(Collection<?> c) { throw uoe(); }
  84     }
  85 
  86     // ---------- List Implementations ----------
  87 
  88     // make a copy, short-circuiting based on implementation class
  89     @SuppressWarnings("unchecked")
  90     static <E> List<E> listCopy(Collection<? extends E> coll) {
  91         if (coll instanceof AbstractImmutableList && coll.getClass() != SubList.class) {
  92             return (List<E>)coll;
  93         } else {
  94             return (List<E>)List.of(coll.toArray());
  95         }
  96     }
  97 





  98     static abstract class AbstractImmutableList<E> extends AbstractImmutableCollection<E>
  99             implements List<E>, RandomAccess {
 100 
 101         // all mutating methods throw UnsupportedOperationException
 102         @Override public void    add(int index, E element) { throw uoe(); }
 103         @Override public boolean addAll(int index, Collection<? extends E> c) { throw uoe(); }
 104         @Override public E       remove(int index) { throw uoe(); }
 105         @Override public void    replaceAll(UnaryOperator<E> operator) { throw uoe(); }
 106         @Override public E       set(int index, E element) { throw uoe(); }
 107         @Override public void    sort(Comparator<? super E> c) { throw uoe(); }
 108 
 109         @Override
 110         public List<E> subList(int fromIndex, int toIndex) {
 111             int size = size();
 112             subListRangeCheck(fromIndex, toIndex, size);
 113             return SubList.fromList(this, fromIndex, toIndex);
 114         }
 115 
 116         static void subListRangeCheck(int fromIndex, int toIndex, int size) {
 117             if (fromIndex < 0)


 387 
 388         @Stable
 389         private final E e1;
 390 
 391         List12(E e0) {
 392             this.e0 = Objects.requireNonNull(e0);
 393             this.e1 = null;
 394         }
 395 
 396         List12(E e0, E e1) {
 397             this.e0 = Objects.requireNonNull(e0);
 398             this.e1 = Objects.requireNonNull(e1);
 399         }
 400 
 401         @Override
 402         public int size() {
 403             return e1 != null ? 2 : 1;
 404         }
 405 
 406         @Override
 407         public boolean isEmpty() {
 408             return false;
 409         }
 410 
 411         @Override
 412         public E get(int index) {
 413             if (index == 0) {
 414                 return e0;
 415             } else if (index == 1 && e1 != null) {
 416                 return e1;
 417             }
 418             throw outOfBounds(index);
 419         }
 420 
 421         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
 422             throw new InvalidObjectException("not serial proxy");
 423         }
 424 
 425         private Object writeReplace() {
 426             if (e1 == null) {
 427                 return new CollSer(CollSer.IMM_LIST, e0);
 428             } else {
 429                 return new CollSer(CollSer.IMM_LIST, e0, e1);
 430             }
 431         }


 468                 EMPTY_LIST = new ListN<>();
 469             }
 470         }
 471 
 472         @Stable
 473         private final E[] elements;
 474 
 475         @SafeVarargs
 476         ListN(E... input) {
 477             // copy and check manually to avoid TOCTOU
 478             @SuppressWarnings("unchecked")
 479             E[] tmp = (E[])new Object[input.length]; // implicit nullcheck of input
 480             for (int i = 0; i < input.length; i++) {
 481                 tmp[i] = Objects.requireNonNull(input[i]);
 482             }
 483             elements = tmp;
 484         }
 485 
 486         @Override
 487         public boolean isEmpty() {
 488             return elements.length == 0;
 489         }
 490 
 491         @Override
 492         public int size() {
 493             return elements.length;
 494         }
 495 
 496         @Override
 497         public E get(int index) {
 498             return elements[index];
 499         }
 500 
 501         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
 502             throw new InvalidObjectException("not serial proxy");
 503         }
 504 
 505         private Object writeReplace() {
 506             return new CollSer(CollSer.IMM_LIST, elements);
 507         }
 508 


 539             } else if (!(o instanceof Set)) {
 540                 return false;
 541             }
 542 
 543             Collection<?> c = (Collection<?>) o;
 544             if (c.size() != size()) {
 545                 return false;
 546             }
 547             for (Object e : c) {
 548                 if (e == null || !contains(e)) {
 549                     return false;
 550                 }
 551             }
 552             return true;
 553         }
 554 
 555         @Override
 556         public abstract int hashCode();
 557     }
 558 





 559     static final class Set12<E> extends AbstractImmutableSet<E>
 560             implements Serializable {
 561 
 562         @Stable
 563         final E e0;
 564         @Stable
 565         final E e1;
 566 
 567         Set12(E e0) {
 568             this.e0 = Objects.requireNonNull(e0);
 569             this.e1 = null;
 570         }
 571 
 572         Set12(E e0, E e1) {
 573             if (e0.equals(Objects.requireNonNull(e1))) { // implicit nullcheck of e0
 574                 throw new IllegalArgumentException("duplicate element: " + e0);
 575             }
 576 
 577             this.e0 = e0;
 578             this.e1 = e1;
 579         }
 580 
 581         @Override
 582         public int size() {
 583             return (e1 == null) ? 1 : 2;
 584         }
 585 
 586         @Override
 587         public boolean isEmpty() {
 588             return false;
 589         }
 590 
 591         @Override
 592         public boolean contains(Object o) {
 593             return o.equals(e0) || o.equals(e1); // implicit nullcheck of o
 594         }
 595 
 596         @Override
 597         public int hashCode() {
 598             return e0.hashCode() + (e1 == null ? 0 : e1.hashCode());
 599         }
 600 
 601         @Override
 602         public Iterator<E> iterator() {
 603             return new Iterator<>() {
 604                 private int idx = size();
 605 
 606                 @Override
 607                 public boolean hasNext() {
 608                     return idx > 0;
 609                 }
 610 
 611                 @Override


 699             size = input.length; // implicit nullcheck of input
 700 
 701             elements = (E[])new Object[EXPAND_FACTOR * input.length];
 702             for (int i = 0; i < input.length; i++) {
 703                 E e = input[i];
 704                 int idx = probe(e); // implicit nullcheck of e
 705                 if (idx >= 0) {
 706                     throw new IllegalArgumentException("duplicate element: " + e);
 707                 } else {
 708                     elements[-(idx + 1)] = e;
 709                 }
 710             }
 711         }
 712 
 713         @Override
 714         public int size() {
 715             return size;
 716         }
 717 
 718         @Override
 719         public boolean isEmpty() {
 720             return size == 0;
 721         }
 722 
 723         @Override
 724         public boolean contains(Object o) {
 725             Objects.requireNonNull(o);
 726             return size > 0 && probe(o) >= 0;
 727         }
 728 
 729         private final class SetNIterator implements Iterator<E> {
 730 
 731             private int remaining;
 732 
 733             private int idx;
 734 
 735             SetNIterator() {
 736                 remaining = size();
 737                 if (remaining > 0) {
 738                     idx = Math.floorMod(SALT, elements.length);
 739                 }
 740             }
 741 
 742             @Override
 743             public boolean hasNext() {


 832         }
 833 
 834         @Override
 835         @SuppressWarnings("unchecked")
 836         public <T> T[] toArray(T[] a) {
 837             T[] array = a.length >= size ? a :
 838                     (T[])Array.newInstance(a.getClass().getComponentType(), size);
 839             Iterator<E> it = iterator();
 840             for (int i = 0; i < size; i++) {
 841                 array[i] = (T)it.next();
 842             }
 843             if (array.length > size) {
 844                 array[size] = null; // null-terminate
 845             }
 846             return array;
 847         }
 848     }
 849 
 850     // ---------- Map Implementations ----------
 851 





 852     abstract static class AbstractImmutableMap<K,V> extends AbstractMap<K,V> implements Serializable {
 853         @Override public void clear() { throw uoe(); }
 854         @Override public V compute(K key, BiFunction<? super K,? super V,? extends V> rf) { throw uoe(); }
 855         @Override public V computeIfAbsent(K key, Function<? super K,? extends V> mf) { throw uoe(); }
 856         @Override public V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> rf) { throw uoe(); }
 857         @Override public V merge(K key, V value, BiFunction<? super V,? super V,? extends V> rf) { throw uoe(); }
 858         @Override public V put(K key, V value) { throw uoe(); }
 859         @Override public void putAll(Map<? extends K,? extends V> m) { throw uoe(); }
 860         @Override public V putIfAbsent(K key, V value) { throw uoe(); }
 861         @Override public V remove(Object key) { throw uoe(); }
 862         @Override public boolean remove(Object key, Object value) { throw uoe(); }
 863         @Override public V replace(K key, V value) { throw uoe(); }
 864         @Override public boolean replace(K key, V oldValue, V newValue) { throw uoe(); }
 865         @Override public void replaceAll(BiFunction<? super K,? super V,? extends V> f) { throw uoe(); }
 866     }
 867 
 868     static final class Map1<K,V> extends AbstractImmutableMap<K,V> {
 869         @Stable
 870         private final K k0;
 871         @Stable
 872         private final V v0;
 873 
 874         Map1(K k0, V v0) {
 875             this.k0 = Objects.requireNonNull(k0);
 876             this.v0 = Objects.requireNonNull(v0);
 877         }
 878 
 879         @Override
 880         public Set<Map.Entry<K,V>> entrySet() {
 881             return Set.of(new KeyValueHolder<>(k0, v0));
 882         }
 883 
 884         @Override
 885         public V get(Object o) {
 886             return o.equals(k0) ? v0 : null; // implicit nullcheck of o
 887         }
 888 
 889         @Override
 890         public boolean containsKey(Object o) {
 891             return o.equals(k0); // implicit nullcheck of o
 892         }
 893 
 894         @Override
 895         public boolean containsValue(Object o) {
 896             return o.equals(v0); // implicit nullcheck of o
 897         }
 898 
 899         @Override
 900         public int size() {
 901             return 1;
 902         }
 903 
 904         @Override
 905         public boolean isEmpty() {
 906             return false;
 907         }
 908 
 909         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
 910             throw new InvalidObjectException("not serial proxy");
 911         }
 912 
 913         private Object writeReplace() {
 914             return new CollSer(CollSer.IMM_MAP, k0, v0);
 915         }
 916 
 917         @Override
 918         public int hashCode() {
 919             return k0.hashCode() ^ v0.hashCode();
 920         }
 921     }
 922 
 923     /**
 924      * An array-based Map implementation. There is a single array "table" that
 925      * contains keys and values interleaved: table[0] is kA, table[1] is vA,
 926      * table[2] is kB, table[3] is vB, etc. The table size must be even. It must
 927      * also be strictly larger than the size (the number of key-value pairs contained
 928      * in the map) so that at least one null key is always present.


1006         @Override
1007         @SuppressWarnings("unchecked")
1008         public V get(Object o) {
1009             if (size == 0) {
1010                 Objects.requireNonNull(o);
1011                 return null;
1012             }
1013             int i = probe(o);
1014             if (i >= 0) {
1015                 return (V)table[i+1];
1016             } else {
1017                 return null;
1018             }
1019         }
1020 
1021         @Override
1022         public int size() {
1023             return size;
1024         }
1025 
1026         @Override
1027         public boolean isEmpty() {
1028             return size == 0;
1029         }
1030 
1031         class MapNIterator implements Iterator<Map.Entry<K,V>> {
1032 
1033             private int remaining;
1034 
1035             private int idx;
1036 
1037             MapNIterator() {
1038                 remaining = size();
1039                 if (remaining > 0) {
1040                     idx = Math.floorMod(SALT, table.length >> 1) << 1;
1041                 }
1042             }
1043 
1044             @Override
1045             public boolean hasNext() {
1046                 return remaining > 0;
1047             }
1048 
1049             private int nextIndex() {
1050                 int idx = this.idx;


1251      * @throws InvalidObjectException if the tag value is illegal or if an exception
1252      *         is thrown during creation of the collection
1253      * @throws ObjectStreamException if another serialization error has occurred
1254      * @since 9
1255      */
1256     private Object readResolve() throws ObjectStreamException {
1257         try {
1258             if (array == null) {
1259                 throw new InvalidObjectException("null array");
1260             }
1261 
1262             // use low order 8 bits to indicate "kind"
1263             // ignore high order 24 bits
1264             switch (tag & 0xff) {
1265                 case IMM_LIST:
1266                     return List.of(array);
1267                 case IMM_SET:
1268                     return Set.of(array);
1269                 case IMM_MAP:
1270                     if (array.length == 0) {
1271                         return ImmutableCollections.MapN.EMPTY_MAP;
1272                     } else if (array.length == 2) {
1273                         return new ImmutableCollections.Map1<>(array[0], array[1]);
1274                     } else {
1275                         return new ImmutableCollections.MapN<>(array);
1276                     }
1277                 default:
1278                     throw new InvalidObjectException(String.format("invalid flags 0x%x", tag));
1279             }
1280         } catch (NullPointerException|IllegalArgumentException ex) {
1281             InvalidObjectException ioe = new InvalidObjectException("invalid object");
1282             ioe.initCause(ex);
1283             throw ioe;
1284         }
1285     }
1286 }


  78         @Override public boolean addAll(Collection<? extends E> c) { throw uoe(); }
  79         @Override public void    clear() { throw uoe(); }
  80         @Override public boolean remove(Object o) { throw uoe(); }
  81         @Override public boolean removeAll(Collection<?> c) { throw uoe(); }
  82         @Override public boolean removeIf(Predicate<? super E> filter) { throw uoe(); }
  83         @Override public boolean retainAll(Collection<?> c) { throw uoe(); }
  84     }
  85 
  86     // ---------- List Implementations ----------
  87 
  88     // make a copy, short-circuiting based on implementation class
  89     @SuppressWarnings("unchecked")
  90     static <E> List<E> listCopy(Collection<? extends E> coll) {
  91         if (coll instanceof AbstractImmutableList && coll.getClass() != SubList.class) {
  92             return (List<E>)coll;
  93         } else {
  94             return (List<E>)List.of(coll.toArray());
  95         }
  96     }
  97 
  98     @SuppressWarnings("unchecked")
  99     static <E> List<E> emptyList() {
 100         return (List<E>) ListN.EMPTY_LIST;
 101     }
 102 
 103     static abstract class AbstractImmutableList<E> extends AbstractImmutableCollection<E>
 104             implements List<E>, RandomAccess {
 105 
 106         // all mutating methods throw UnsupportedOperationException
 107         @Override public void    add(int index, E element) { throw uoe(); }
 108         @Override public boolean addAll(int index, Collection<? extends E> c) { throw uoe(); }
 109         @Override public E       remove(int index) { throw uoe(); }
 110         @Override public void    replaceAll(UnaryOperator<E> operator) { throw uoe(); }
 111         @Override public E       set(int index, E element) { throw uoe(); }
 112         @Override public void    sort(Comparator<? super E> c) { throw uoe(); }
 113 
 114         @Override
 115         public List<E> subList(int fromIndex, int toIndex) {
 116             int size = size();
 117             subListRangeCheck(fromIndex, toIndex, size);
 118             return SubList.fromList(this, fromIndex, toIndex);
 119         }
 120 
 121         static void subListRangeCheck(int fromIndex, int toIndex, int size) {
 122             if (fromIndex < 0)


 392 
 393         @Stable
 394         private final E e1;
 395 
 396         List12(E e0) {
 397             this.e0 = Objects.requireNonNull(e0);
 398             this.e1 = null;
 399         }
 400 
 401         List12(E e0, E e1) {
 402             this.e0 = Objects.requireNonNull(e0);
 403             this.e1 = Objects.requireNonNull(e1);
 404         }
 405 
 406         @Override
 407         public int size() {
 408             return e1 != null ? 2 : 1;
 409         }
 410 
 411         @Override





 412         public E get(int index) {
 413             if (index == 0) {
 414                 return e0;
 415             } else if (index == 1 && e1 != null) {
 416                 return e1;
 417             }
 418             throw outOfBounds(index);
 419         }
 420 
 421         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
 422             throw new InvalidObjectException("not serial proxy");
 423         }
 424 
 425         private Object writeReplace() {
 426             if (e1 == null) {
 427                 return new CollSer(CollSer.IMM_LIST, e0);
 428             } else {
 429                 return new CollSer(CollSer.IMM_LIST, e0, e1);
 430             }
 431         }


 468                 EMPTY_LIST = new ListN<>();
 469             }
 470         }
 471 
 472         @Stable
 473         private final E[] elements;
 474 
 475         @SafeVarargs
 476         ListN(E... input) {
 477             // copy and check manually to avoid TOCTOU
 478             @SuppressWarnings("unchecked")
 479             E[] tmp = (E[])new Object[input.length]; // implicit nullcheck of input
 480             for (int i = 0; i < input.length; i++) {
 481                 tmp[i] = Objects.requireNonNull(input[i]);
 482             }
 483             elements = tmp;
 484         }
 485 
 486         @Override
 487         public boolean isEmpty() {
 488             return size() == 0;
 489         }
 490 
 491         @Override
 492         public int size() {
 493             return elements.length;
 494         }
 495 
 496         @Override
 497         public E get(int index) {
 498             return elements[index];
 499         }
 500 
 501         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
 502             throw new InvalidObjectException("not serial proxy");
 503         }
 504 
 505         private Object writeReplace() {
 506             return new CollSer(CollSer.IMM_LIST, elements);
 507         }
 508 


 539             } else if (!(o instanceof Set)) {
 540                 return false;
 541             }
 542 
 543             Collection<?> c = (Collection<?>) o;
 544             if (c.size() != size()) {
 545                 return false;
 546             }
 547             for (Object e : c) {
 548                 if (e == null || !contains(e)) {
 549                     return false;
 550                 }
 551             }
 552             return true;
 553         }
 554 
 555         @Override
 556         public abstract int hashCode();
 557     }
 558 
 559     @SuppressWarnings("unchecked")
 560     static <E> Set<E> emptySet() {
 561         return (Set<E>) SetN.EMPTY_SET;
 562     }
 563 
 564     static final class Set12<E> extends AbstractImmutableSet<E>
 565             implements Serializable {
 566 
 567         @Stable
 568         final E e0;
 569         @Stable
 570         final E e1;
 571 
 572         Set12(E e0) {
 573             this.e0 = Objects.requireNonNull(e0);
 574             this.e1 = null;
 575         }
 576 
 577         Set12(E e0, E e1) {
 578             if (e0.equals(Objects.requireNonNull(e1))) { // implicit nullcheck of e0
 579                 throw new IllegalArgumentException("duplicate element: " + e0);
 580             }
 581 
 582             this.e0 = e0;
 583             this.e1 = e1;
 584         }
 585 
 586         @Override
 587         public int size() {
 588             return (e1 == null) ? 1 : 2;
 589         }
 590 
 591         @Override





 592         public boolean contains(Object o) {
 593             return o.equals(e0) || o.equals(e1); // implicit nullcheck of o
 594         }
 595 
 596         @Override
 597         public int hashCode() {
 598             return e0.hashCode() + (e1 == null ? 0 : e1.hashCode());
 599         }
 600 
 601         @Override
 602         public Iterator<E> iterator() {
 603             return new Iterator<>() {
 604                 private int idx = size();
 605 
 606                 @Override
 607                 public boolean hasNext() {
 608                     return idx > 0;
 609                 }
 610 
 611                 @Override


 699             size = input.length; // implicit nullcheck of input
 700 
 701             elements = (E[])new Object[EXPAND_FACTOR * input.length];
 702             for (int i = 0; i < input.length; i++) {
 703                 E e = input[i];
 704                 int idx = probe(e); // implicit nullcheck of e
 705                 if (idx >= 0) {
 706                     throw new IllegalArgumentException("duplicate element: " + e);
 707                 } else {
 708                     elements[-(idx + 1)] = e;
 709                 }
 710             }
 711         }
 712 
 713         @Override
 714         public int size() {
 715             return size;
 716         }
 717 
 718         @Override





 719         public boolean contains(Object o) {
 720             Objects.requireNonNull(o);
 721             return size > 0 && probe(o) >= 0;
 722         }
 723 
 724         private final class SetNIterator implements Iterator<E> {
 725 
 726             private int remaining;
 727 
 728             private int idx;
 729 
 730             SetNIterator() {
 731                 remaining = size();
 732                 if (remaining > 0) {
 733                     idx = Math.floorMod(SALT, elements.length);
 734                 }
 735             }
 736 
 737             @Override
 738             public boolean hasNext() {


 827         }
 828 
 829         @Override
 830         @SuppressWarnings("unchecked")
 831         public <T> T[] toArray(T[] a) {
 832             T[] array = a.length >= size ? a :
 833                     (T[])Array.newInstance(a.getClass().getComponentType(), size);
 834             Iterator<E> it = iterator();
 835             for (int i = 0; i < size; i++) {
 836                 array[i] = (T)it.next();
 837             }
 838             if (array.length > size) {
 839                 array[size] = null; // null-terminate
 840             }
 841             return array;
 842         }
 843     }
 844 
 845     // ---------- Map Implementations ----------
 846 
 847     @SuppressWarnings("unchecked")
 848     static <K,V> Map<K,V> emptyMap() {
 849         return (Map<K,V>) MapN.EMPTY_MAP;
 850     }
 851 
 852     abstract static class AbstractImmutableMap<K,V> extends AbstractMap<K,V> implements Serializable {
 853         @Override public void clear() { throw uoe(); }
 854         @Override public V compute(K key, BiFunction<? super K,? super V,? extends V> rf) { throw uoe(); }
 855         @Override public V computeIfAbsent(K key, Function<? super K,? extends V> mf) { throw uoe(); }
 856         @Override public V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> rf) { throw uoe(); }
 857         @Override public V merge(K key, V value, BiFunction<? super V,? super V,? extends V> rf) { throw uoe(); }
 858         @Override public V put(K key, V value) { throw uoe(); }
 859         @Override public void putAll(Map<? extends K,? extends V> m) { throw uoe(); }
 860         @Override public V putIfAbsent(K key, V value) { throw uoe(); }
 861         @Override public V remove(Object key) { throw uoe(); }
 862         @Override public boolean remove(Object key, Object value) { throw uoe(); }
 863         @Override public V replace(K key, V value) { throw uoe(); }
 864         @Override public boolean replace(K key, V oldValue, V newValue) { throw uoe(); }
 865         @Override public void replaceAll(BiFunction<? super K,? super V,? extends V> f) { throw uoe(); }
 866     }
 867 
 868     static final class Map1<K,V> extends AbstractImmutableMap<K,V> {
 869         @Stable
 870         private final K k0;
 871         @Stable
 872         private final V v0;
 873 
 874         Map1(K k0, V v0) {
 875             this.k0 = Objects.requireNonNull(k0);
 876             this.v0 = Objects.requireNonNull(v0);
 877         }
 878 
 879         @Override
 880         public Set<Map.Entry<K,V>> entrySet() {
 881             return Set.of(new KeyValueHolder<>(k0, v0));
 882         }
 883 
 884         @Override





 885         public boolean containsKey(Object o) {
 886             return o.equals(k0); // implicit nullcheck of o
 887         }
 888 
 889         @Override
 890         public boolean containsValue(Object o) {
 891             return o.equals(v0); // implicit nullcheck of o
 892         }
 893 










 894         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
 895             throw new InvalidObjectException("not serial proxy");
 896         }
 897 
 898         private Object writeReplace() {
 899             return new CollSer(CollSer.IMM_MAP, k0, v0);
 900         }
 901 
 902         @Override
 903         public int hashCode() {
 904             return k0.hashCode() ^ v0.hashCode();
 905         }
 906     }
 907 
 908     /**
 909      * An array-based Map implementation. There is a single array "table" that
 910      * contains keys and values interleaved: table[0] is kA, table[1] is vA,
 911      * table[2] is kB, table[3] is vB, etc. The table size must be even. It must
 912      * also be strictly larger than the size (the number of key-value pairs contained
 913      * in the map) so that at least one null key is always present.


 991         @Override
 992         @SuppressWarnings("unchecked")
 993         public V get(Object o) {
 994             if (size == 0) {
 995                 Objects.requireNonNull(o);
 996                 return null;
 997             }
 998             int i = probe(o);
 999             if (i >= 0) {
1000                 return (V)table[i+1];
1001             } else {
1002                 return null;
1003             }
1004         }
1005 
1006         @Override
1007         public int size() {
1008             return size;
1009         }
1010 





1011         class MapNIterator implements Iterator<Map.Entry<K,V>> {
1012 
1013             private int remaining;
1014 
1015             private int idx;
1016 
1017             MapNIterator() {
1018                 remaining = size();
1019                 if (remaining > 0) {
1020                     idx = Math.floorMod(SALT, table.length >> 1) << 1;
1021                 }
1022             }
1023 
1024             @Override
1025             public boolean hasNext() {
1026                 return remaining > 0;
1027             }
1028 
1029             private int nextIndex() {
1030                 int idx = this.idx;


1231      * @throws InvalidObjectException if the tag value is illegal or if an exception
1232      *         is thrown during creation of the collection
1233      * @throws ObjectStreamException if another serialization error has occurred
1234      * @since 9
1235      */
1236     private Object readResolve() throws ObjectStreamException {
1237         try {
1238             if (array == null) {
1239                 throw new InvalidObjectException("null array");
1240             }
1241 
1242             // use low order 8 bits to indicate "kind"
1243             // ignore high order 24 bits
1244             switch (tag & 0xff) {
1245                 case IMM_LIST:
1246                     return List.of(array);
1247                 case IMM_SET:
1248                     return Set.of(array);
1249                 case IMM_MAP:
1250                     if (array.length == 0) {
1251                         return ImmutableCollections.emptyMap();
1252                     } else if (array.length == 2) {
1253                         return new ImmutableCollections.Map1<>(array[0], array[1]);
1254                     } else {
1255                         return new ImmutableCollections.MapN<>(array);
1256                     }
1257                 default:
1258                     throw new InvalidObjectException(String.format("invalid flags 0x%x", tag));
1259             }
1260         } catch (NullPointerException|IllegalArgumentException ex) {
1261             InvalidObjectException ioe = new InvalidObjectException("invalid object");
1262             ioe.initCause(ex);
1263             throw ioe;
1264         }
1265     }
1266 }
< prev index next >