src/java.base/share/classes/java/util/ImmutableCollections.java
author smarks
Thu, 21 Jun 2018 08:45:57 -0700
changeset 50698 c1f7ece09b84
parent 49919 96d4658eb7f2
child 50809 6ff774d73176
permissions -rw-r--r--
8203184: List.copyOf() fails to copy sublists Reviewed-by: psandoz
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
     1
/*
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
     2
 * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
     4
 *
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    10
 *
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    15
 * accompanied this code).
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    16
 *
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    20
 *
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    23
 * questions.
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    24
 */
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    25
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    26
package java.util;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    27
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    28
import java.io.IOException;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    29
import java.io.InvalidObjectException;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    30
import java.io.ObjectInputStream;
38567
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
    31
import java.io.ObjectOutputStream;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    32
import java.io.ObjectStreamException;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    33
import java.io.Serializable;
40788
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
    34
import java.util.function.BiFunction;
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
    35
import java.util.function.Function;
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
    36
import java.util.function.Predicate;
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
    37
import java.util.function.UnaryOperator;
47423
4fc2a4a29f3d 8174109: Better queuing priorities
smarks
parents: 47216
diff changeset
    38
import jdk.internal.misc.SharedSecrets;
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
    39
import jdk.internal.vm.annotation.Stable;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    40
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    41
/**
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    42
 * Container class for immutable collections. Not part of the public API.
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    43
 * Mainly for namespace management and shared infrastructure.
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    44
 *
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    45
 * Serial warnings are suppressed throughout because all implementation
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    46
 * classes use a serial proxy and thus have no need to declare serialVersionUID.
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    47
 */
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    48
@SuppressWarnings("serial")
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    49
class ImmutableCollections {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    50
    /**
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    51
     * A "salt" value used for randomizing iteration order. This is initialized once
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    52
     * and stays constant for the lifetime of the JVM. It need not be truly random, but
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    53
     * it needs to vary sufficiently from one run to the next so that iteration order
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    54
     * will vary between JVM runs.
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    55
     */
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    56
    static final int SALT;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    57
    static {
41914
b09ce4c1536e 8156079: consider making empty instances singletons
smarks
parents: 40788
diff changeset
    58
        long nt = System.nanoTime();
b09ce4c1536e 8156079: consider making empty instances singletons
smarks
parents: 40788
diff changeset
    59
        SALT = (int)((nt >>> 32) ^ nt);
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    60
    }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    61
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    62
    /** No instances. */
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    63
    private ImmutableCollections() { }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    64
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    65
    /**
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    66
     * The reciprocal of load factor. Given a number of elements
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    67
     * to store, multiply by this factor to get the table size.
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    68
     */
41914
b09ce4c1536e 8156079: consider making empty instances singletons
smarks
parents: 40788
diff changeset
    69
    static final int EXPAND_FACTOR = 2;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
    70
40788
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
    71
    static UnsupportedOperationException uoe() { return new UnsupportedOperationException(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
    72
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
    73
    static abstract class AbstractImmutableCollection<E> extends AbstractCollection<E> {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
    74
        // all mutating methods throw UnsupportedOperationException
40788
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
    75
        @Override public boolean add(E e) { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
    76
        @Override public boolean addAll(Collection<? extends E> c) { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
    77
        @Override public void    clear() { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
    78
        @Override public boolean remove(Object o) { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
    79
        @Override public boolean removeAll(Collection<?> c) { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
    80
        @Override public boolean removeIf(Predicate<? super E> filter) { throw uoe(); }
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
    81
        @Override public boolean retainAll(Collection<?> c) { throw uoe(); }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
    82
    }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
    83
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
    84
    // ---------- List Implementations ----------
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
    85
50698
c1f7ece09b84 8203184: List.copyOf() fails to copy sublists
smarks
parents: 49919
diff changeset
    86
    // make a copy, short-circuiting based on implementation class
c1f7ece09b84 8203184: List.copyOf() fails to copy sublists
smarks
parents: 49919
diff changeset
    87
    @SuppressWarnings("unchecked")
c1f7ece09b84 8203184: List.copyOf() fails to copy sublists
smarks
parents: 49919
diff changeset
    88
    static <E> List<E> listCopy(Collection<? extends E> coll) {
c1f7ece09b84 8203184: List.copyOf() fails to copy sublists
smarks
parents: 49919
diff changeset
    89
        if (coll instanceof AbstractImmutableList && coll.getClass() != SubList.class) {
c1f7ece09b84 8203184: List.copyOf() fails to copy sublists
smarks
parents: 49919
diff changeset
    90
            return (List<E>)coll;
c1f7ece09b84 8203184: List.copyOf() fails to copy sublists
smarks
parents: 49919
diff changeset
    91
        } else {
c1f7ece09b84 8203184: List.copyOf() fails to copy sublists
smarks
parents: 49919
diff changeset
    92
            return (List<E>)List.of(coll.toArray());
c1f7ece09b84 8203184: List.copyOf() fails to copy sublists
smarks
parents: 49919
diff changeset
    93
        }
c1f7ece09b84 8203184: List.copyOf() fails to copy sublists
smarks
parents: 49919
diff changeset
    94
    }
c1f7ece09b84 8203184: List.copyOf() fails to copy sublists
smarks
parents: 49919
diff changeset
    95
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
    96
    @SuppressWarnings("unchecked")
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
    97
    static <E> List<E> emptyList() {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
    98
        return (List<E>) ListN.EMPTY_LIST;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
    99
    }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   100
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   101
    static abstract class AbstractImmutableList<E> extends AbstractImmutableCollection<E>
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   102
            implements List<E>, RandomAccess {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   103
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   104
        // all mutating methods throw UnsupportedOperationException
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   105
        @Override public void    add(int index, E element) { throw uoe(); }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   106
        @Override public boolean addAll(int index, Collection<? extends E> c) { throw uoe(); }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   107
        @Override public E       remove(int index) { throw uoe(); }
40788
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   108
        @Override public void    replaceAll(UnaryOperator<E> operator) { throw uoe(); }
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   109
        @Override public E       set(int index, E element) { throw uoe(); }
40788
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   110
        @Override public void    sort(Comparator<? super E> c) { throw uoe(); }
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   111
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   112
        @Override
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   113
        public List<E> subList(int fromIndex, int toIndex) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   114
            int size = size();
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   115
            subListRangeCheck(fromIndex, toIndex, size);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   116
            return SubList.fromList(this, fromIndex, toIndex);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   117
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   118
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   119
        static void subListRangeCheck(int fromIndex, int toIndex, int size) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   120
            if (fromIndex < 0)
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   121
                throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   122
            if (toIndex > size)
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   123
                throw new IndexOutOfBoundsException("toIndex = " + toIndex);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   124
            if (fromIndex > toIndex)
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   125
                throw new IllegalArgumentException("fromIndex(" + fromIndex +
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   126
                        ") > toIndex(" + toIndex + ")");
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   127
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   128
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   129
        @Override
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   130
        public Iterator<E> iterator() {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   131
            return new ListItr<E>(this, size());
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   132
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   133
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   134
        @Override
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   135
        public ListIterator<E> listIterator() {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   136
            return listIterator(0);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   137
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   138
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   139
        @Override
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   140
        public ListIterator<E> listIterator(final int index) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   141
            int size = size();
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   142
            if (index < 0 || index > size) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   143
                throw outOfBounds(index);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   144
            }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   145
            return new ListItr<E>(this, size, index);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   146
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   147
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   148
        @Override
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   149
        public boolean equals(Object o) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   150
            if (o == this) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   151
                return true;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   152
            }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   153
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   154
            if (!(o instanceof List)) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   155
                return false;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   156
            }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   157
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   158
            Iterator<?> oit = ((List<?>) o).iterator();
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   159
            for (int i = 0, s = size(); i < s; i++) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   160
                if (!oit.hasNext() || !get(i).equals(oit.next())) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   161
                    return false;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   162
                }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   163
            }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   164
            return !oit.hasNext();
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   165
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   166
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   167
        @Override
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   168
        public int indexOf(Object o) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   169
            Objects.requireNonNull(o);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   170
            for (int i = 0, s = size(); i < s; i++) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   171
                if (o.equals(get(i))) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   172
                    return i;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   173
                }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   174
            }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   175
            return -1;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   176
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   177
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   178
        @Override
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   179
        public int lastIndexOf(Object o) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   180
            Objects.requireNonNull(o);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   181
            for (int i = size() - 1; i >= 0; i--) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   182
                if (o.equals(get(i))) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   183
                    return i;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   184
                }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   185
            }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   186
            return -1;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   187
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   188
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   189
        @Override
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   190
        public int hashCode() {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   191
            int hash = 1;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   192
            for (int i = 0, s = size(); i < s; i++) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   193
                hash = 31 * hash + get(i).hashCode();
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   194
            }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   195
            return hash;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   196
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   197
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   198
        @Override
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   199
        public boolean contains(Object o) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   200
            return indexOf(o) >= 0;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   201
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   202
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   203
        IndexOutOfBoundsException outOfBounds(int index) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   204
            return new IndexOutOfBoundsException("Index: " + index + " Size: " + size());
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   205
        }
40788
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   206
    }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   207
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   208
    static final class ListItr<E> implements ListIterator<E> {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   209
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   210
        @Stable
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   211
        private final List<E> list;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   212
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   213
        @Stable
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   214
        private final int size;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   215
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   216
        private int cursor;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   217
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   218
        ListItr(List<E> list, int size) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   219
            this(list, size, 0);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   220
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   221
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   222
        ListItr(List<E> list, int size, int index) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   223
            this.list = list;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   224
            this.size = size;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   225
            this.cursor = index;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   226
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   227
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   228
        public boolean hasNext() {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   229
            return cursor != size;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   230
        }
41914
b09ce4c1536e 8156079: consider making empty instances singletons
smarks
parents: 40788
diff changeset
   231
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   232
        public E next() {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   233
            try {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   234
                int i = cursor;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   235
                E next = list.get(i);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   236
                cursor = i + 1;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   237
                return next;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   238
            } catch (IndexOutOfBoundsException e) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   239
                throw new NoSuchElementException();
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   240
            }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   241
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   242
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   243
        public void remove() {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   244
            throw uoe();
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   245
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   246
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   247
        public boolean hasPrevious() {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   248
            return cursor != 0;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   249
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   250
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   251
        public E previous() {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   252
            try {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   253
                int i = cursor - 1;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   254
                E previous = list.get(i);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   255
                cursor = i;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   256
                return previous;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   257
            } catch (IndexOutOfBoundsException e) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   258
                throw new NoSuchElementException();
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   259
            }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   260
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   261
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   262
        public int nextIndex() {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   263
            return cursor;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   264
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   265
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   266
        public int previousIndex() {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   267
            return cursor - 1;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   268
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   269
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   270
        public void set(E e) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   271
            throw uoe();
41914
b09ce4c1536e 8156079: consider making empty instances singletons
smarks
parents: 40788
diff changeset
   272
        }
b09ce4c1536e 8156079: consider making empty instances singletons
smarks
parents: 40788
diff changeset
   273
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   274
        public void add(E e) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   275
            throw uoe();
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   276
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   277
    }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   278
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   279
    static final class SubList<E> extends AbstractImmutableList<E>
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   280
            implements RandomAccess {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   281
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   282
        @Stable
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   283
        private final List<E> root;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   284
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   285
        @Stable
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   286
        private final int offset;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   287
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   288
        @Stable
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   289
        private final int size;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   290
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   291
        private SubList(List<E> root, int offset, int size) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   292
            this.root = root;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   293
            this.offset = offset;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   294
            this.size = size;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   295
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   296
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   297
        /**
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   298
         * Constructs a sublist of another SubList.
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   299
         */
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   300
        static <E> SubList<E> fromSubList(SubList<E> parent, int fromIndex, int toIndex) {
49919
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   301
            return new SubList<>(parent.root, parent.offset + fromIndex, toIndex - fromIndex);
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   302
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   303
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   304
        /**
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   305
         * Constructs a sublist of an arbitrary AbstractImmutableList, which is
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   306
         * not a SubList itself.
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   307
         */
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   308
        static <E> SubList<E> fromList(List<E> list, int fromIndex, int toIndex) {
49919
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   309
            return new SubList<>(list, fromIndex, toIndex - fromIndex);
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   310
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   311
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   312
        public E get(int index) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   313
            Objects.checkIndex(index, size);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   314
            return root.get(offset + index);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   315
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   316
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   317
        public int size() {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   318
            return size;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   319
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   320
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   321
        public Iterator<E> iterator() {
49919
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   322
            return new ListItr<>(this, size());
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   323
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   324
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   325
        public ListIterator<E> listIterator(int index) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   326
            rangeCheck(index);
49919
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   327
            return new ListItr<>(this, size(), index);
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   328
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   329
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   330
        public List<E> subList(int fromIndex, int toIndex) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   331
            subListRangeCheck(fromIndex, toIndex, size);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   332
            return SubList.fromSubList(this, fromIndex, toIndex);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   333
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   334
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   335
        private void rangeCheck(int index) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   336
            if (index < 0 || index > size) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   337
                throw outOfBounds(index);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   338
            }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   339
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   340
    }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   341
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   342
    static final class List12<E> extends AbstractImmutableList<E>
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   343
            implements Serializable {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   344
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   345
        @Stable
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   346
        private final E e0;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   347
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   348
        @Stable
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   349
        private final E e1;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   350
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   351
        List12(E e0) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   352
            this.e0 = Objects.requireNonNull(e0);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   353
            this.e1 = null;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   354
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   355
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   356
        List12(E e0, E e1) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   357
            this.e0 = Objects.requireNonNull(e0);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   358
            this.e1 = Objects.requireNonNull(e1);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   359
        }
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   360
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   361
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   362
        public int size() {
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   363
            return e1 != null ? 2 : 1;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   364
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   365
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   366
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   367
        public E get(int index) {
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   368
            if (index == 0) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   369
                return e0;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   370
            } else if (index == 1 && e1 != null) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   371
                return e1;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   372
            }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   373
            throw outOfBounds(index);
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   374
        }
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   375
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   376
        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   377
            throw new InvalidObjectException("not serial proxy");
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   378
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   379
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   380
        private Object writeReplace() {
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   381
            if (e1 == null) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   382
                return new CollSer(CollSer.IMM_LIST, e0);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   383
            } else {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   384
                return new CollSer(CollSer.IMM_LIST, e0, e1);
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   385
            }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   386
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   387
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   388
    }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   389
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   390
    static final class ListN<E> extends AbstractImmutableList<E>
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   391
            implements Serializable {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   392
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   393
        static final List<?> EMPTY_LIST = new ListN<>();
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   394
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   395
        @Stable
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   396
        private final E[] elements;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   397
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   398
        @SafeVarargs
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   399
        ListN(E... input) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   400
            // copy and check manually to avoid TOCTOU
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   401
            @SuppressWarnings("unchecked")
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   402
            E[] tmp = (E[])new Object[input.length]; // implicit nullcheck of input
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   403
            for (int i = 0; i < input.length; i++) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   404
                tmp[i] = Objects.requireNonNull(input[i]);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   405
            }
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   406
            elements = tmp;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   407
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   408
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   409
        @Override
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   410
        public boolean isEmpty() {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   411
            return size() == 0;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   412
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   413
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   414
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   415
        public int size() {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   416
            return elements.length;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   417
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   418
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   419
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   420
        public E get(int index) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   421
            return elements[index];
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   422
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   423
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   424
        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   425
            throw new InvalidObjectException("not serial proxy");
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   426
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   427
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   428
        private Object writeReplace() {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   429
            return new CollSer(CollSer.IMM_LIST, elements);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   430
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   431
    }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   432
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   433
    // ---------- Set Implementations ----------
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   434
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   435
    static abstract class AbstractImmutableSet<E> extends AbstractImmutableCollection<E>
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   436
            implements Set<E> {
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   437
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   438
        @Override
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   439
        public boolean equals(Object o) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   440
            if (o == this) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   441
                return true;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   442
            } else if (!(o instanceof Set)) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   443
                return false;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   444
            }
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   445
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   446
            Collection<?> c = (Collection<?>) o;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   447
            if (c.size() != size()) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   448
                return false;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   449
            }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   450
            for (Object e : c) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   451
                if (e == null || !contains(e)) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   452
                    return false;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   453
                }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   454
            }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   455
            return true;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   456
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   457
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   458
        @Override
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   459
        public abstract int hashCode();
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   460
    }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   461
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   462
    @SuppressWarnings("unchecked")
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   463
    static <E> Set<E> emptySet() {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   464
        return (Set<E>) SetN.EMPTY_SET;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   465
    }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   466
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   467
    static final class Set12<E> extends AbstractImmutableSet<E>
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   468
            implements Serializable {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   469
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   470
        @Stable
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   471
        final E e0;
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   472
        @Stable
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   473
        final E e1;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   474
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   475
        Set12(E e0) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   476
            this.e0 = Objects.requireNonNull(e0);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   477
            this.e1 = null;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   478
        }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   479
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   480
        Set12(E e0, E e1) {
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   481
            if (e0.equals(Objects.requireNonNull(e1))) { // implicit nullcheck of e0
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   482
                throw new IllegalArgumentException("duplicate element: " + e0);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   483
            }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   484
49919
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   485
            this.e0 = e0;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   486
            this.e1 = e1;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   487
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   488
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   489
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   490
        public int size() {
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   491
            return (e1 == null) ? 1 : 2;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   492
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   493
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   494
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   495
        public boolean contains(Object o) {
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   496
            return o.equals(e0) || o.equals(e1); // implicit nullcheck of o
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   497
        }
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   498
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   499
        @Override
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   500
        public int hashCode() {
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   501
            return e0.hashCode() + (e1 == null ? 0 : e1.hashCode());
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   502
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   503
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   504
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   505
        public Iterator<E> iterator() {
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   506
            return new Iterator<>() {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   507
                private int idx = size();
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   508
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   509
                @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   510
                public boolean hasNext() {
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   511
                    return idx > 0;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   512
                }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   513
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   514
                @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   515
                public E next() {
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   516
                    if (idx == 1) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   517
                        idx = 0;
49919
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   518
                        return SALT >= 0 || e1 == null ? e0 : e1;
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   519
                    } else if (idx == 2) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   520
                        idx = 1;
49919
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   521
                        return SALT >= 0 ? e1 : e0;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   522
                    } else {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   523
                        throw new NoSuchElementException();
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   524
                    }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   525
                }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   526
            };
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   527
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   528
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   529
        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   530
            throw new InvalidObjectException("not serial proxy");
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   531
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   532
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   533
        private Object writeReplace() {
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   534
            if (e1 == null) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   535
                return new CollSer(CollSer.IMM_SET, e0);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   536
            } else {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   537
                return new CollSer(CollSer.IMM_SET, e0, e1);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   538
            }
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   539
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   540
    }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   541
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   542
    /**
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   543
     * An array-based Set implementation. The element array must be strictly
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   544
     * larger than the size (the number of contained elements) so that at
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   545
     * least one null is always present.
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   546
     * @param <E> the element type
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   547
     */
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   548
    static final class SetN<E> extends AbstractImmutableSet<E>
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   549
            implements Serializable {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   550
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   551
        static final Set<?> EMPTY_SET = new SetN<>();
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   552
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   553
        @Stable
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   554
        final E[] elements;
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   555
        @Stable
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   556
        final int size;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   557
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   558
        @SafeVarargs
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   559
        @SuppressWarnings("unchecked")
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   560
        SetN(E... input) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   561
            size = input.length; // implicit nullcheck of input
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   562
41914
b09ce4c1536e 8156079: consider making empty instances singletons
smarks
parents: 40788
diff changeset
   563
            elements = (E[])new Object[EXPAND_FACTOR * input.length];
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   564
            for (int i = 0; i < input.length; i++) {
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   565
                E e = input[i];
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   566
                int idx = probe(e); // implicit nullcheck of e
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   567
                if (idx >= 0) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   568
                    throw new IllegalArgumentException("duplicate element: " + e);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   569
                } else {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   570
                    elements[-(idx + 1)] = e;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   571
                }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   572
            }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   573
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   574
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   575
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   576
        public int size() {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   577
            return size;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   578
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   579
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   580
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   581
        public boolean contains(Object o) {
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   582
            Objects.requireNonNull(o);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   583
            return size > 0 && probe(o) >= 0;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   584
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   585
49919
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   586
        private final class SetNIterator implements Iterator<E> {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   587
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   588
            private int remaining;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   589
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   590
            private int idx;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   591
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   592
            SetNIterator() {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   593
                remaining = size();
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   594
                if (remaining > 0) {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   595
                    idx = Math.floorMod(SALT, elements.length);
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   596
                }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   597
            }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   598
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   599
            @Override
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   600
            public boolean hasNext() {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   601
                return remaining > 0;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   602
            }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   603
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   604
            private int nextIndex() {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   605
                int idx = this.idx;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   606
                if (SALT >= 0) {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   607
                    if (++idx >= elements.length) {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   608
                        idx = 0;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   609
                    }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   610
                } else {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   611
                    if (--idx < 0) {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   612
                        idx = elements.length - 1;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   613
                    }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   614
                }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   615
                return this.idx = idx;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   616
            }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   617
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   618
            @Override
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   619
            public E next() {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   620
                if (hasNext()) {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   621
                    E element;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   622
                    // skip null elements
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   623
                    while ((element = elements[nextIndex()]) == null) {}
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   624
                    remaining--;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   625
                    return element;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   626
                } else {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   627
                    throw new NoSuchElementException();
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   628
                }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   629
            }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   630
        }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   631
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   632
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   633
        public Iterator<E> iterator() {
49919
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   634
            return new SetNIterator();
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   635
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   636
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   637
        @Override
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   638
        public int hashCode() {
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   639
            int h = 0;
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   640
            for (E e : elements) {
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   641
                if (e != null) {
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   642
                    h += e.hashCode();
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   643
                }
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   644
            }
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   645
            return h;
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   646
        }
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   647
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   648
        // returns index at which element is present; or if absent,
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   649
        // (-i - 1) where i is location where element should be inserted.
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   650
        // Callers are relying on this method to perform an implicit nullcheck
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   651
        // of pe
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   652
        private int probe(Object pe) {
49919
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   653
            int idx = Math.floorMod(pe.hashCode(), elements.length);
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   654
            while (true) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   655
                E ee = elements[idx];
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   656
                if (ee == null) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   657
                    return -idx - 1;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   658
                } else if (pe.equals(ee)) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   659
                    return idx;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   660
                } else if (++idx == elements.length) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   661
                    idx = 0;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   662
                }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   663
            }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   664
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   665
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   666
        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   667
            throw new InvalidObjectException("not serial proxy");
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   668
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   669
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   670
        private Object writeReplace() {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   671
            Object[] array = new Object[size];
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   672
            int dest = 0;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   673
            for (Object o : elements) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   674
                if (o != null) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   675
                    array[dest++] = o;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   676
                }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   677
            }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   678
            return new CollSer(CollSer.IMM_SET, array);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   679
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   680
    }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   681
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   682
    // ---------- Map Implementations ----------
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   683
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   684
    @SuppressWarnings("unchecked")
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   685
    static <K,V> Map<K,V> emptyMap() {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   686
        return (Map<K,V>) MapN.EMPTY_MAP;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   687
    }
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   688
40788
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   689
    abstract static class AbstractImmutableMap<K,V> extends AbstractMap<K,V> implements Serializable {
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   690
        @Override public void clear() { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   691
        @Override public V compute(K key, BiFunction<? super K,? super V,? extends V> rf) { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   692
        @Override public V computeIfAbsent(K key, Function<? super K,? extends V> mf) { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   693
        @Override public V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> rf) { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   694
        @Override public V merge(K key, V value, BiFunction<? super V,? super V,? extends V> rf) { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   695
        @Override public V put(K key, V value) { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   696
        @Override public void putAll(Map<? extends K,? extends V> m) { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   697
        @Override public V putIfAbsent(K key, V value) { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   698
        @Override public V remove(Object key) { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   699
        @Override public boolean remove(Object key, Object value) { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   700
        @Override public V replace(K key, V value) { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   701
        @Override public boolean replace(K key, V oldValue, V newValue) { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   702
        @Override public void replaceAll(BiFunction<? super K,? super V,? extends V> f) { throw uoe(); }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   703
    }
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   704
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   705
    static final class Map1<K,V> extends AbstractImmutableMap<K,V> {
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   706
        @Stable
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   707
        private final K k0;
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   708
        @Stable
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   709
        private final V v0;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   710
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   711
        Map1(K k0, V v0) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   712
            this.k0 = Objects.requireNonNull(k0);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   713
            this.v0 = Objects.requireNonNull(v0);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   714
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   715
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   716
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   717
        public Set<Map.Entry<K,V>> entrySet() {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   718
            return Set.of(new KeyValueHolder<>(k0, v0));
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   719
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   720
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   721
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   722
        public boolean containsKey(Object o) {
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   723
            return o.equals(k0); // implicit nullcheck of o
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   724
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   725
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   726
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   727
        public boolean containsValue(Object o) {
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   728
            return o.equals(v0); // implicit nullcheck of o
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   729
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   730
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   731
        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   732
            throw new InvalidObjectException("not serial proxy");
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   733
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   734
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   735
        private Object writeReplace() {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   736
            return new CollSer(CollSer.IMM_MAP, k0, v0);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   737
        }
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   738
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   739
        @Override
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   740
        public int hashCode() {
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   741
            return k0.hashCode() ^ v0.hashCode();
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   742
        }
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   743
    }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   744
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   745
    /**
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   746
     * An array-based Map implementation. There is a single array "table" that
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   747
     * contains keys and values interleaved: table[0] is kA, table[1] is vA,
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   748
     * table[2] is kB, table[3] is vB, etc. The table size must be even. It must
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   749
     * also be strictly larger than the size (the number of key-value pairs contained
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   750
     * in the map) so that at least one null key is always present.
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   751
     * @param <K> the key type
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   752
     * @param <V> the value type
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   753
     */
40788
01ffe34b7340 8159404: throw UnsupportedOperationException unconditionally for mutator methods
smarks
parents: 38567
diff changeset
   754
    static final class MapN<K,V> extends AbstractImmutableMap<K,V> {
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   755
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   756
        static final Map<?,?> EMPTY_MAP = new MapN<>();
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   757
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   758
        @Stable
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   759
        final Object[] table; // pairs of key, value
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   760
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   761
        @Stable
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   762
        final int size; // number of pairs
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   763
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   764
        MapN(Object... input) {
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   765
            if ((input.length & 1) != 0) { // implicit nullcheck of input
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   766
                throw new InternalError("length is odd");
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   767
            }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   768
            size = input.length >> 1;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   769
41914
b09ce4c1536e 8156079: consider making empty instances singletons
smarks
parents: 40788
diff changeset
   770
            int len = EXPAND_FACTOR * input.length;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   771
            len = (len + 1) & ~1; // ensure table is even length
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   772
            table = new Object[len];
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   773
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   774
            for (int i = 0; i < input.length; i += 2) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   775
                @SuppressWarnings("unchecked")
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   776
                    K k = Objects.requireNonNull((K)input[i]);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   777
                @SuppressWarnings("unchecked")
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   778
                    V v = Objects.requireNonNull((V)input[i+1]);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   779
                int idx = probe(k);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   780
                if (idx >= 0) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   781
                    throw new IllegalArgumentException("duplicate key: " + k);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   782
                } else {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   783
                    int dest = -(idx + 1);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   784
                    table[dest] = k;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   785
                    table[dest+1] = v;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   786
                }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   787
            }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   788
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   789
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   790
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   791
        public boolean containsKey(Object o) {
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   792
            Objects.requireNonNull(o);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   793
            return size > 0 && probe(o) >= 0;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   794
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   795
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   796
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   797
        public boolean containsValue(Object o) {
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   798
            Objects.requireNonNull(o);
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   799
            for (int i = 1; i < table.length; i += 2) {
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   800
                Object v = table[i];
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   801
                if (v != null && o.equals(v)) {
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   802
                    return true;
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   803
                }
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   804
            }
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   805
            return false;
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   806
        }
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   807
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   808
        @Override
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   809
        public int hashCode() {
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   810
            int hash = 0;
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   811
            for (int i = 0; i < table.length; i += 2) {
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   812
                Object k = table[i];
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   813
                if (k != null) {
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   814
                    hash += k.hashCode() ^ table[i + 1].hashCode();
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   815
                }
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   816
            }
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   817
            return hash;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   818
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   819
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   820
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   821
        @SuppressWarnings("unchecked")
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   822
        public V get(Object o) {
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   823
            if (size == 0) {
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   824
                Objects.requireNonNull(o);
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   825
                return null;
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   826
            }
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   827
            int i = probe(o);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   828
            if (i >= 0) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   829
                return (V)table[i+1];
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   830
            } else {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   831
                return null;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   832
            }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   833
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   834
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   835
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   836
        public int size() {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   837
            return size;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   838
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   839
49919
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   840
        class MapNIterator implements Iterator<Map.Entry<K,V>> {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   841
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   842
            private int remaining;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   843
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   844
            private int idx;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   845
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   846
            MapNIterator() {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   847
                remaining = size();
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   848
                if (remaining > 0) {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   849
                    idx = Math.floorMod(SALT, table.length >> 1) << 1;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   850
                }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   851
            }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   852
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   853
            @Override
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   854
            public boolean hasNext() {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   855
                return remaining > 0;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   856
            }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   857
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   858
            private int nextIndex() {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   859
                int idx = this.idx;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   860
                if (SALT >= 0) {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   861
                    if ((idx += 2) >= table.length) {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   862
                        idx = 0;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   863
                    }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   864
                } else {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   865
                    if ((idx -= 2) < 0) {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   866
                        idx = table.length - 2;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   867
                    }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   868
                }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   869
                return this.idx = idx;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   870
            }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   871
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   872
            @Override
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   873
            public Map.Entry<K,V> next() {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   874
                if (hasNext()) {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   875
                    while (table[nextIndex()] == null) {}
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   876
                    @SuppressWarnings("unchecked")
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   877
                    Map.Entry<K,V> e =
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   878
                            new KeyValueHolder<>((K)table[idx], (V)table[idx+1]);
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   879
                    remaining--;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   880
                    return e;
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   881
                } else {
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   882
                    throw new NoSuchElementException();
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   883
                }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   884
            }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   885
        }
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   886
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   887
        @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   888
        public Set<Map.Entry<K,V>> entrySet() {
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
   889
            return new AbstractSet<>() {
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   890
                @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   891
                public int size() {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   892
                    return MapN.this.size;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   893
                }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   894
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   895
                @Override
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   896
                public Iterator<Map.Entry<K,V>> iterator() {
49919
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   897
                    return new MapNIterator();
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   898
                }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   899
            };
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   900
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   901
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   902
        // returns index at which the probe key is present; or if absent,
43068
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   903
        // (-i - 1) where i is location where element should be inserted.
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   904
        // Callers are relying on this method to perform an implicit nullcheck
df01087b2c43 8166365: Small immutable collections should provide optimized implementations when possible
redestad
parents: 41914
diff changeset
   905
        // of pk.
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   906
        private int probe(Object pk) {
49919
96d4658eb7f2 8201650: Move iteration order randomization of unmodifiable Set and Map to iterators
redestad
parents: 49283
diff changeset
   907
            int idx = Math.floorMod(pk.hashCode(), table.length >> 1) << 1;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   908
            while (true) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   909
                @SuppressWarnings("unchecked")
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   910
                K ek = (K)table[idx];
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   911
                if (ek == null) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   912
                    return -idx - 1;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   913
                } else if (pk.equals(ek)) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   914
                    return idx;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   915
                } else if ((idx += 2) == table.length) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   916
                    idx = 0;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   917
                }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   918
            }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   919
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   920
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   921
        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   922
            throw new InvalidObjectException("not serial proxy");
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   923
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   924
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   925
        private Object writeReplace() {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   926
            Object[] array = new Object[2 * size];
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   927
            int len = table.length;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   928
            int dest = 0;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   929
            for (int i = 0; i < len; i += 2) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   930
                if (table[i] != null) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   931
                    array[dest++] = table[i];
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   932
                    array[dest++] = table[i+1];
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   933
                }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   934
            }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   935
            return new CollSer(CollSer.IMM_MAP, array);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   936
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   937
    }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   938
}
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   939
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   940
// ---------- Serialization Proxy ----------
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   941
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   942
/**
38567
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   943
 * A unified serialization proxy class for the immutable collections.
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   944
 *
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   945
 * @serial
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   946
 * @since 9
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   947
 */
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   948
final class CollSer implements Serializable {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   949
    private static final long serialVersionUID = 6309168927139932177L;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   950
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   951
    static final int IMM_LIST = 1;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   952
    static final int IMM_SET = 2;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   953
    static final int IMM_MAP = 3;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   954
38567
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   955
    /**
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   956
     * Indicates the type of collection that is serialized.
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   957
     * The low order 8 bits have the value 1 for an immutable
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   958
     * {@code List}, 2 for an immutable {@code Set}, and 3 for
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   959
     * an immutable {@code Map}. Any other value causes an
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   960
     * {@link InvalidObjectException} to be thrown. The high
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   961
     * order 24 bits are zero when an instance is serialized,
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   962
     * and they are ignored when an instance is deserialized.
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   963
     * They can thus be used by future implementations without
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   964
     * causing compatibility issues.
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   965
     *
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   966
     * <p>The tag value also determines the interpretation of the
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   967
     * transient {@code Object[] array} field.
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   968
     * For {@code List} and {@code Set}, the array's length is the size
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   969
     * of the collection, and the array contains the elements of the collection.
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   970
     * Null elements are not allowed. For {@code Set}, duplicate elements
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   971
     * are not allowed.
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   972
     *
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   973
     * <p>For {@code Map}, the array's length is twice the number of mappings
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   974
     * present in the map. The array length is necessarily even.
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   975
     * The array contains a succession of key and value pairs:
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   976
     * {@code k1, v1, k2, v2, ..., kN, vN.} Nulls are not allowed,
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   977
     * and duplicate keys are not allowed.
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   978
     *
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   979
     * @serial
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   980
     * @since 9
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   981
     */
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   982
    private final int tag;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   983
38567
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   984
    /**
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   985
     * @serial
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   986
     * @since 9
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   987
     */
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   988
    private transient Object[] array;
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   989
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   990
    CollSer(int t, Object... a) {
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   991
        tag = t;
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   992
        array = a;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   993
    }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
   994
38567
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   995
    /**
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   996
     * Reads objects from the stream and stores them
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   997
     * in the transient {@code Object[] array} field.
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   998
     *
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
   999
     * @serialData
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1000
     * A nonnegative int, indicating the count of objects,
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1001
     * followed by that many objects.
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1002
     *
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1003
     * @param ois the ObjectInputStream from which data is read
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1004
     * @throws IOException if an I/O error occurs
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1005
     * @throws ClassNotFoundException if a serialized class cannot be loaded
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1006
     * @throws InvalidObjectException if the count is negative
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1007
     * @since 9
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1008
     */
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1009
    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1010
        ois.defaultReadObject();
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1011
        int len = ois.readInt();
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1012
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1013
        if (len < 0) {
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1014
            throw new InvalidObjectException("negative length " + len);
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1015
        }
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1016
47423
4fc2a4a29f3d 8174109: Better queuing priorities
smarks
parents: 47216
diff changeset
  1017
        SharedSecrets.getJavaObjectInputStreamAccess().checkArray(ois, Object[].class, len);
38567
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1018
        Object[] a = new Object[len];
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1019
        for (int i = 0; i < len; i++) {
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1020
            a[i] = ois.readObject();
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1021
        }
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1022
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1023
        array = a;
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1024
    }
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1025
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1026
    /**
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1027
     * Writes objects to the stream from
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1028
     * the transient {@code Object[] array} field.
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1029
     *
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1030
     * @serialData
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1031
     * A nonnegative int, indicating the count of objects,
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1032
     * followed by that many objects.
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1033
     *
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1034
     * @param oos the ObjectOutputStream to which data is written
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1035
     * @throws IOException if an I/O error occurs
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1036
     * @since 9
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1037
     */
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1038
    private void writeObject(ObjectOutputStream oos) throws IOException {
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1039
        oos.defaultWriteObject();
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1040
        oos.writeInt(array.length);
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1041
        for (int i = 0; i < array.length; i++) {
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1042
            oos.writeObject(array[i]);
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1043
        }
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1044
    }
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1045
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1046
    /**
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1047
     * Creates and returns an immutable collection from this proxy class.
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1048
     * The instance returned is created as if by calling one of the
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1049
     * static factory methods for
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1050
     * <a href="List.html#immutable">List</a>,
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1051
     * <a href="Map.html#immutable">Map</a>, or
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1052
     * <a href="Set.html#immutable">Set</a>.
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1053
     * This proxy class is the serial form for all immutable collection instances,
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1054
     * regardless of implementation type. This is necessary to ensure that the
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1055
     * existence of any particular implementation type is kept out of the
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1056
     * serialized form.
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1057
     *
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1058
     * @return a collection created from this proxy object
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1059
     * @throws InvalidObjectException if the tag value is illegal or if an exception
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1060
     *         is thrown during creation of the collection
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1061
     * @throws ObjectStreamException if another serialization error has occurred
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1062
     * @since 9
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1063
     */
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1064
    private Object readResolve() throws ObjectStreamException {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1065
        try {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1066
            if (array == null) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1067
                throw new InvalidObjectException("null array");
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1068
            }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1069
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1070
            // use low order 8 bits to indicate "kind"
38567
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1071
            // ignore high order 24 bits
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1072
            switch (tag & 0xff) {
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1073
                case IMM_LIST:
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1074
                    return List.of(array);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1075
                case IMM_SET:
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1076
                    return Set.of(array);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1077
                case IMM_MAP:
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1078
                    if (array.length == 0) {
49283
a14ede52a278 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
redestad
parents: 47423
diff changeset
  1079
                        return ImmutableCollections.emptyMap();
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1080
                    } else if (array.length == 2) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1081
                        return new ImmutableCollections.Map1<>(array[0], array[1]);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1082
                    } else {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1083
                        return new ImmutableCollections.MapN<>(array);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1084
                    }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1085
                default:
38567
6d4c5a278fff 8133977: add specification for serialized forms
smarks
parents: 37802
diff changeset
  1086
                    throw new InvalidObjectException(String.format("invalid flags 0x%x", tag));
37802
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1087
            }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1088
        } catch (NullPointerException|IllegalArgumentException ex) {
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1089
            InvalidObjectException ioe = new InvalidObjectException("invalid object");
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1090
            ioe.initCause(ex);
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1091
            throw ioe;
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1092
        }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1093
    }
91fc9ac7b8b3 8139233: add initial compact immutable collection implementations
smarks
parents:
diff changeset
  1094
}