src/java.base/share/classes/java/util/ImmutableCollections.java
changeset 53202 02e648ae46c3
parent 52887 0d89f672c62e
child 54428 6aedb80a6fd4
--- a/src/java.base/share/classes/java/util/ImmutableCollections.java	Tue Jan 08 13:04:04 2019 -0800
+++ b/src/java.base/share/classes/java/util/ImmutableCollections.java	Wed Jan 09 01:06:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
+import java.lang.reflect.Array;
 import java.util.function.BiFunction;
 import java.util.function.Function;
 import java.util.function.Predicate;
@@ -357,6 +358,30 @@
                 throw outOfBounds(index);
             }
         }
+
+        @Override
+        public Object[] toArray() {
+            Object[] array = new Object[size];
+            for (int i = 0; i < size; i++) {
+                array[i] = get(i);
+            }
+            return array;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public <T> T[] toArray(T[] a) {
+            T[] array = a.length >= size ? a :
+                    (T[])java.lang.reflect.Array
+                            .newInstance(a.getClass().getComponentType(), size);
+            for (int i = 0; i < size; i++) {
+                array[i] = (T)get(i);
+            }
+            if (array.length > size) {
+                array[size] = null; // null-terminate
+            }
+            return array;
+        }
     }
 
     static final class List12<E> extends AbstractImmutableList<E>
@@ -405,6 +430,30 @@
             }
         }
 
+        @Override
+        public Object[] toArray() {
+            if (e1 == null) {
+                return new Object[] { e0 };
+            } else {
+                return new Object[] { e0, e1 };
+            }
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public <T> T[] toArray(T[] a) {
+            int size = e1 == null ? 1 : 2;
+            T[] array = a.length >= size ? a :
+                    (T[])Array.newInstance(a.getClass().getComponentType(), size);
+            array[0] = (T)e0;
+            if (size == 2) {
+                array[1] = (T)e1;
+            }
+            if (array.length > size) {
+                array[size] = null; // null-terminate
+            }
+            return array;
+        }
     }
 
     static final class ListN<E> extends AbstractImmutableList<E>
@@ -456,6 +505,26 @@
         private Object writeReplace() {
             return new CollSer(CollSer.IMM_LIST, elements);
         }
+
+        @Override
+        public Object[] toArray() {
+            return Arrays.copyOf(elements, elements.length);
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public <T> T[] toArray(T[] a) {
+            int size = elements.length;
+            if (a.length < size) {
+                // Make a new array of a's runtime type, but my contents:
+                return (T[]) Arrays.copyOf(elements, size, a.getClass());
+            }
+            System.arraycopy(elements, 0, a, 0, size);
+            if (a.length > size) {
+                a[size] = null; // null-terminate
+            }
+            return a;
+        }
     }
 
     // ---------- Set Implementations ----------
@@ -565,8 +634,41 @@
                 return new CollSer(CollSer.IMM_SET, e0, e1);
             }
         }
+
+        @Override
+        public Object[] toArray() {
+            if (e1 == null) {
+                return new Object[] { e0 };
+            } else if (SALT >= 0) {
+                return new Object[] { e1, e0 };
+            } else {
+                return new Object[] { e0, e1 };
+            }
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public <T> T[] toArray(T[] a) {
+            int size = e1 == null ? 1 : 2;
+            T[] array = a.length >= size ? a :
+                    (T[])Array.newInstance(a.getClass().getComponentType(), size);
+            if (size == 1) {
+                array[0] = (T)e0;
+            } else if (SALT >= 0) {
+                array[0] = (T)e1;
+                array[1] = (T)e0;
+            } else {
+                array[0] = (T)e0;
+                array[1] = (T)e1;
+            }
+            if (array.length > size) {
+                array[size] = null; // null-terminate
+            }
+            return array;
+        }
     }
 
+
     /**
      * An array-based Set implementation. The element array must be strictly
      * larger than the size (the number of contained elements) so that at
@@ -653,7 +755,7 @@
 
             @Override
             public E next() {
-                if (hasNext()) {
+                if (remaining > 0) {
                     E element;
                     // skip null elements
                     while ((element = elements[nextIndex()]) == null) {}
@@ -713,6 +815,31 @@
             }
             return new CollSer(CollSer.IMM_SET, array);
         }
+
+        @Override
+        public Object[] toArray() {
+            Object[] array = new Object[size];
+            Iterator<E> it = iterator();
+            for (int i = 0; i < size; i++) {
+                array[i] = it.next();
+            }
+            return array;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public <T> T[] toArray(T[] a) {
+            T[] array = a.length >= size ? a :
+                    (T[])Array.newInstance(a.getClass().getComponentType(), size);
+            Iterator<E> it = iterator();
+            for (int i = 0; i < size; i++) {
+                array[i] = (T)it.next();
+            }
+            if (array.length > size) {
+                array[size] = null; // null-terminate
+            }
+            return array;
+        }
     }
 
     // ---------- Map Implementations ----------
@@ -915,8 +1042,9 @@
 
             @Override
             public Map.Entry<K,V> next() {
-                if (hasNext()) {
-                    while (table[nextIndex()] == null) {}
+                if (remaining > 0) {
+                    int idx;
+                    while (table[idx = nextIndex()] == null) {}
                     @SuppressWarnings("unchecked")
                     Map.Entry<K,V> e =
                             new KeyValueHolder<>((K)table[idx], (V)table[idx+1]);