< prev index next >
src/java.base/share/classes/java/util/ImmutableCollections.java
Print this page
rev 47862 : imported patch immu0
*** 57,66 ****
--- 57,68 ----
static {
long nt = System.nanoTime();
SALT = (int)((nt >>> 32) ^ nt);
}
+ private static final Object NULL = new Object();
+
/** No instances. */
private ImmutableCollections() { }
/**
* The reciprocal of load factor. Given a number of elements
*** 84,142 ****
@Override public void replaceAll(UnaryOperator<E> operator) { throw uoe(); }
@Override public boolean retainAll(Collection<?> c) { throw uoe(); }
@Override public void sort(Comparator<? super E> c) { throw uoe(); }
}
! static final class List0<E> extends AbstractImmutableList<E> {
! private static final List0<?> INSTANCE = new List0<>();
!
! @SuppressWarnings("unchecked")
! static <T> List0<T> instance() {
! return (List0<T>) INSTANCE;
! }
!
! private List0() { }
! @Override
! public int size() {
! return 0;
! }
! @Override
! public E get(int index) {
! Objects.checkIndex(index, 0); // always throws IndexOutOfBoundsException
! return null; // but the compiler doesn't know this
! }
! @Override
! public Iterator<E> iterator() {
! return Collections.emptyIterator();
! }
!
! private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
! throw new InvalidObjectException("not serial proxy");
! }
!
! private Object writeReplace() {
! return new CollSer(CollSer.IMM_LIST);
! }
!
! @Override
! public boolean contains(Object o) {
! Objects.requireNonNull(o);
! return false;
}
! @Override
! public boolean containsAll(Collection<?> o) {
! return o.isEmpty(); // implicit nullcheck of o
}
! @Override
! public int hashCode() {
! return 1;
! }
}
static final class List1<E> extends AbstractImmutableList<E> {
@Stable
private final E e0;
--- 86,114 ----
@Override public void replaceAll(UnaryOperator<E> operator) { throw uoe(); }
@Override public boolean retainAll(Collection<?> c) { throw uoe(); }
@Override public void sort(Comparator<? super E> c) { throw uoe(); }
}
! static final List<?> EMPTY_LIST = new ListN<>();
! static final Set<?> EMPTY_SET = new SetN<>();
! static final Map<?,?> EMPTY_MAP = new MapN<>();
! @SuppressWarnings("unchecked")
! static <T> List<T> emptyList() {
! return (List<T>) EMPTY_LIST;
}
! @SuppressWarnings("unchecked")
! static <T> Set<T> emptySet() {
! return (Set<T>) EMPTY_SET;
}
! @SuppressWarnings("unchecked")
! static <K,V> Map<K,V> emptyMap() {
! return (Map<K,V>) EMPTY_MAP;
}
static final class List1<E> extends AbstractImmutableList<E> {
@Stable
private final E e0;
*** 173,228 ****
public int hashCode() {
return 31 + e0.hashCode();
}
}
- static final class List2<E> extends AbstractImmutableList<E> {
- @Stable
- private final E e0;
- @Stable
- private final E e1;
-
- List2(E e0, E e1) {
- this.e0 = Objects.requireNonNull(e0);
- this.e1 = Objects.requireNonNull(e1);
- }
-
- @Override
- public int size() {
- return 2;
- }
-
- @Override
- public E get(int index) {
- Objects.checkIndex(index, 2);
- if (index == 0) {
- return e0;
- } else { // index == 1
- return e1;
- }
- }
-
- @Override
- public boolean contains(Object o) {
- return o.equals(e0) || o.equals(e1); // implicit nullcheck of o
- }
-
- @Override
- public int hashCode() {
- int hash = 31 + e0.hashCode();
- return 31 * hash + e1.hashCode();
- }
-
- private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
- throw new InvalidObjectException("not serial proxy");
- }
-
- private Object writeReplace() {
- return new CollSer(CollSer.IMM_LIST, e0, e1);
- }
- }
-
static final class ListN<E> extends AbstractImmutableList<E> {
@Stable
private final E[] elements;
@SafeVarargs
--- 145,154 ----
*** 285,339 ****
@Override public boolean removeAll(Collection<?> c) { throw uoe(); }
@Override public boolean removeIf(Predicate<? super E> filter) { throw uoe(); }
@Override public boolean retainAll(Collection<?> c) { throw uoe(); }
}
- static final class Set0<E> extends AbstractImmutableSet<E> {
- private static final Set0<?> INSTANCE = new Set0<>();
-
- @SuppressWarnings("unchecked")
- static <T> Set0<T> instance() {
- return (Set0<T>) INSTANCE;
- }
-
- private Set0() { }
-
- @Override
- public int size() {
- return 0;
- }
-
- @Override
- public boolean contains(Object o) {
- Objects.requireNonNull(o);
- return false;
- }
-
- @Override
- public boolean containsAll(Collection<?> o) {
- return o.isEmpty(); // implicit nullcheck of o
- }
-
- @Override
- public Iterator<E> iterator() {
- return Collections.emptyIterator();
- }
-
- private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
- throw new InvalidObjectException("not serial proxy");
- }
-
- private Object writeReplace() {
- return new CollSer(CollSer.IMM_SET);
- }
-
- @Override
- public int hashCode() {
- return 0;
- }
- }
-
static final class Set1<E> extends AbstractImmutableSet<E> {
@Stable
private final E e0;
Set1(E e0) {
--- 211,220 ----
*** 367,445 ****
public int hashCode() {
return e0.hashCode();
}
}
- static final class Set2<E> extends AbstractImmutableSet<E> {
- @Stable
- final E e0;
- @Stable
- final E e1;
-
- Set2(E e0, E e1) {
- if (e0.equals(Objects.requireNonNull(e1))) { // implicit nullcheck of e0
- throw new IllegalArgumentException("duplicate element: " + e0);
- }
-
- if (SALT >= 0) {
- this.e0 = e0;
- this.e1 = e1;
- } else {
- this.e0 = e1;
- this.e1 = e0;
- }
- }
-
- @Override
- public int size() {
- return 2;
- }
-
- @Override
- public boolean contains(Object o) {
- return o.equals(e0) || o.equals(e1); // implicit nullcheck of o
- }
-
- @Override
- public int hashCode() {
- return e0.hashCode() + e1.hashCode();
- }
-
- @Override
- public Iterator<E> iterator() {
- return new Iterator<E>() {
- private int idx = 0;
-
- @Override
- public boolean hasNext() {
- return idx < 2;
- }
-
- @Override
- public E next() {
- if (idx == 0) {
- idx = 1;
- return e0;
- } else if (idx == 1) {
- idx = 2;
- return e1;
- } else {
- throw new NoSuchElementException();
- }
- }
- };
- }
-
- private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
- throw new InvalidObjectException("not serial proxy");
- }
-
- private Object writeReplace() {
- return new CollSer(CollSer.IMM_SET, e0, e1);
- }
- }
-
/**
* An array-based Set implementation. The element array must be strictly
* larger than the size (the number of contained elements) so that at
* least one null is always present.
* @param <E> the element type
--- 248,257 ----
*** 472,482 ****
return size;
}
@Override
public boolean contains(Object o) {
! return probe(o) >= 0; // implicit nullcheck of o
}
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
--- 284,295 ----
return size;
}
@Override
public boolean contains(Object o) {
! Objects.requireNonNull(0);
! return size > 0 && probe(o) >= 0; // implicit nullcheck of o
}
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
*** 563,613 ****
@Override public V replace(K key, V value) { throw uoe(); }
@Override public boolean replace(K key, V oldValue, V newValue) { throw uoe(); }
@Override public void replaceAll(BiFunction<? super K,? super V,? extends V> f) { throw uoe(); }
}
- static final class Map0<K,V> extends AbstractImmutableMap<K,V> {
- private static final Map0<?,?> INSTANCE = new Map0<>();
-
- @SuppressWarnings("unchecked")
- static <K,V> Map0<K,V> instance() {
- return (Map0<K,V>) INSTANCE;
- }
-
- private Map0() { }
-
- @Override
- public Set<Map.Entry<K,V>> entrySet() {
- return Set.of();
- }
-
- @Override
- public boolean containsKey(Object o) {
- Objects.requireNonNull(o);
- return false;
- }
-
- @Override
- public boolean containsValue(Object o) {
- Objects.requireNonNull(o);
- return false;
- }
-
- private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
- throw new InvalidObjectException("not serial proxy");
- }
-
- private Object writeReplace() {
- return new CollSer(CollSer.IMM_MAP);
- }
-
- @Override
- public int hashCode() {
- return 0;
- }
- }
-
static final class Map1<K,V> extends AbstractImmutableMap<K,V> {
@Stable
private final K k0;
@Stable
private final V v0;
--- 376,385 ----
*** 656,666 ****
* @param <V> the value type
*/
static final class MapN<K,V> extends AbstractImmutableMap<K,V> {
@Stable
final Object[] table; // pairs of key, value
- @Stable
final int size; // number of pairs
MapN(Object... input) {
if ((input.length & 1) != 0) { // implicit nullcheck of input
throw new InternalError("length is odd");
--- 428,437 ----
*** 687,697 ****
}
}
@Override
public boolean containsKey(Object o) {
! return probe(o) >= 0; // implicit nullcheck of o
}
@Override
public boolean containsValue(Object o) {
for (int i = 1; i < table.length; i += 2) {
--- 458,469 ----
}
}
@Override
public boolean containsKey(Object o) {
! Objects.requireNonNull(0);
! return size > 0 && probe(o) >= 0;
}
@Override
public boolean containsValue(Object o) {
for (int i = 1; i < table.length; i += 2) {
*** 716,725 ****
--- 488,500 ----
}
@Override
@SuppressWarnings("unchecked")
public V get(Object o) {
+ if (size == 0) {
+ return null;
+ }
int i = probe(o);
if (i >= 0) {
return (V)table[i+1];
} else {
return null;
*** 946,956 ****
return List.of(array);
case IMM_SET:
return Set.of(array);
case IMM_MAP:
if (array.length == 0) {
! return ImmutableCollections.Map0.instance();
} else if (array.length == 2) {
return new ImmutableCollections.Map1<>(array[0], array[1]);
} else {
return new ImmutableCollections.MapN<>(array);
}
--- 721,731 ----
return List.of(array);
case IMM_SET:
return Set.of(array);
case IMM_MAP:
if (array.length == 0) {
! return ImmutableCollections.emptyMap();
} else if (array.length == 2) {
return new ImmutableCollections.Map1<>(array[0], array[1]);
} else {
return new ImmutableCollections.MapN<>(array);
}
< prev index next >