< prev index next >

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

Print this page
rev 49279 : 8193128: Reduce number of implementation classes returned by List/Set/Map.of()
8191418: List.of().indexOf(null) doesn't throw NullPointerException
Reviewed-by: smarks, jrose, martin, plevart
rev 49280 : imported patch reduceclasses_changes

@@ -68,17 +68,10 @@
      */
     static final int EXPAND_FACTOR = 2;
 
     static UnsupportedOperationException uoe() { return new UnsupportedOperationException(); }
 
-    // ---------- List Implementations ----------
-
-    @SuppressWarnings("unchecked")
-    static <E> List<E> emptyList() {
-        return (List<E>) ListN.EMPTY_LIST;
-    }
-
     static abstract class AbstractImmutableCollection<E> extends AbstractCollection<E> {
         // all mutating methods throw UnsupportedOperationException
         @Override public boolean add(E e) { throw uoe(); }
         @Override public boolean addAll(Collection<? extends E> c) { throw uoe(); }
         @Override public void    clear() { throw uoe(); }

@@ -86,35 +79,15 @@
         @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 abstract class AbstractImmutableSet<E> extends AbstractImmutableCollection<E>
-            implements Set<E> {
-
-        @Override
-        public boolean equals(Object o) {
-            if (o == this) {
-                return true;
-            } else if (!(o instanceof Set)) {
-                return false;
-            }
-
-            Collection<?> c = (Collection<?>) o;
-            if (c.size() != size()) {
-                return false;
-            }
-            for (Object e : c) {
-                if (e == null || !contains(e)) {
-                    return false;
-                }
-            }
-            return true;
-        }
+    // ---------- List Implementations ----------
 
-        @Override
-        public abstract int hashCode();
+    @SuppressWarnings("unchecked")
+    static <E> List<E> emptyList() {
+        return (List<E>) ListN.EMPTY_LIST;
     }
 
     static abstract class AbstractImmutableList<E> extends AbstractImmutableCollection<E>
             implements List<E>, RandomAccess {
 

@@ -128,182 +101,149 @@
 
         @Override
         public List<E> subList(int fromIndex, int toIndex) {
             int size = size();
             subListRangeCheck(fromIndex, toIndex, size);
-            return new SubList<E>(this, fromIndex, toIndex);
+            return SubList.fromList(this, fromIndex, toIndex);
         }
 
-        private static final class SubList<E> extends AbstractImmutableList<E>
-                implements RandomAccess {
-            private final List<E> root;
-            final int offset;
-            int size;
-
-            /**
-             * Constructs a sublist of an arbitrary AbstractList, which is
-             * not a SubList itself.
-             */
-            SubList(List<E> root, int fromIndex, int toIndex) {
-                this.root = root;
-                this.offset = fromIndex;
-                this.size = toIndex - fromIndex;
-            }
-
-            /**
-             * Constructs a sublist of another SubList.
-             */
-            SubList(SubList<E> parent, int fromIndex, int toIndex) {
-                this.root = parent.root;
-                this.offset = parent.offset + fromIndex;
-                this.size = toIndex - fromIndex;
+        static void subListRangeCheck(int fromIndex, int toIndex, int size) {
+            if (fromIndex < 0)
+                throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
+            if (toIndex > size)
+                throw new IndexOutOfBoundsException("toIndex = " + toIndex);
+            if (fromIndex > toIndex)
+                throw new IllegalArgumentException("fromIndex(" + fromIndex +
+                        ") > toIndex(" + toIndex + ")");
             }
 
-            public E get(int index) {
-                Objects.checkIndex(index, size);
-                return root.get(offset + index);
+        @Override
+        public Iterator<E> iterator() {
+            return new ListItr<E>(this, size());
             }
 
-            public int size() {
-                return size;
+        @Override
+        public ListIterator<E> listIterator() {
+            return listIterator(0);
             }
 
-            public Iterator<E> iterator() {
-                return listIterator();
+        @Override
+        public ListIterator<E> listIterator(final int index) {
+            int size = size();
+            if (index < 0 || index > size) {
+                throw outOfBounds(index);
             }
-
-            public ListIterator<E> listIterator(int index) {
-                rangeCheck(index);
-
-                ListIterator<E> i = root.listIterator(offset + index);
-
-                return new ListIterator<>() {
-
-                    public boolean hasNext() {
-                        return nextIndex() < size;
+            return new ListItr<E>(this, size, index);
                     }
 
-                    public E next() {
-                        if (hasNext()) {
-                            return i.next();
-                        } else {
-                            throw new NoSuchElementException();
-                        }
+        @Override
+        public boolean equals(Object o) {
+            if (o == this) {
+                return true;
                     }
 
-                    public boolean hasPrevious() {
-                        return previousIndex() >= 0;
+            if (!(o instanceof List)) {
+                return false;
                     }
 
-                    public E previous() {
-                        if (hasPrevious()) {
-                            return i.previous();
-                        } else {
-                            throw new NoSuchElementException();
+            Iterator<?> oit = ((List<?>) o).iterator();
+            for (int i = 0, s = size(); i < s; i++) {
+                if (!oit.hasNext() || !get(i).equals(oit.next())) {
+                    return false;
                         }
                     }
-
-                    public int nextIndex() {
-                        return i.nextIndex() - offset;
+            return !oit.hasNext();
                     }
 
-                    public int previousIndex() {
-                        return i.previousIndex() - offset;
+        @Override
+        public int indexOf(Object o) {
+            Objects.requireNonNull(o);
+            for (int i = 0, s = size(); i < s; i++) {
+                if (o.equals(get(i))) {
+                    return i;
                     }
-
-                    public void remove() { throw uoe(); }
-                    public void set(E e) { throw uoe(); }
-                    public void add(E e) { throw uoe(); }
-                };
             }
-
-            public List<E> subList(int fromIndex, int toIndex) {
-                subListRangeCheck(fromIndex, toIndex, size);
-                return new SubList<>(this, fromIndex, toIndex);
+            return -1;
             }
 
-            private void rangeCheck(int index) {
-                if (index < 0 || index > size) {
-                    throw outOfBounds(index);
-                }
+        @Override
+        public int lastIndexOf(Object o) {
+            Objects.requireNonNull(o);
+            for (int i = size() - 1; i >= 0; i--) {
+                if (o.equals(get(i))) {
+                    return i;
             }
         }
-
-        static void subListRangeCheck(int fromIndex, int toIndex, int size) {
-            if (fromIndex < 0)
-                throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
-            if (toIndex > size)
-                throw new IndexOutOfBoundsException("toIndex = " + toIndex);
-            if (fromIndex > toIndex)
-                throw new IllegalArgumentException("fromIndex(" + fromIndex +
-                        ") > toIndex(" + toIndex + ")");
+            return -1;
         }
 
         @Override
-        public Iterator<E> iterator() {
-            return new Itr(size());
+        public int hashCode() {
+            int hash = 1;
+            for (int i = 0, s = size(); i < s; i++) {
+                hash = 31 * hash + get(i).hashCode();
+            }
+            return hash;
         }
 
         @Override
-        public ListIterator<E> listIterator() {
-            return listIterator(0);
+        public boolean contains(Object o) {
+            return indexOf(o) >= 0;
         }
 
-        @Override
-        public ListIterator<E> listIterator(final int index) {
-            int size = size();
-            if (index < 0 || index > size) {
-                throw outOfBounds(index);
+        IndexOutOfBoundsException outOfBounds(int index) {
+            return new IndexOutOfBoundsException("Index: " + index + " Size: " + size());
             }
-            return new ListItr(index, size);
         }
 
-        private class Itr implements Iterator<E> {
+    static final class ListItr<E> implements ListIterator<E> {
 
-            int cursor;
+        @Stable
+        private final List<E> list;
 
+        @Stable
             private final int size;
 
-            Itr(int size) {
+        private int cursor;
+
+        ListItr(List<E> list, int size) {
+            this(list, size, 0);
+        }
+
+        ListItr(List<E> list, int size, int index) {
+            this.list = list;
                 this.size = size;
+            this.cursor = index;
             }
 
             public boolean hasNext() {
                 return cursor != size;
             }
 
             public E next() {
                 try {
                     int i = cursor;
-                    E next = get(i);
+                E next = list.get(i);
                     cursor = i + 1;
                     return next;
                 } catch (IndexOutOfBoundsException e) {
                     throw new NoSuchElementException();
                 }
             }
 
             public void remove() {
                 throw uoe();
             }
-        }
-
-        private class ListItr extends Itr implements ListIterator<E> {
-
-            ListItr(int index, int size) {
-                super(size);
-                cursor = index;
-            }
 
             public boolean hasPrevious() {
                 return cursor != 0;
             }
 
             public E previous() {
                 try {
                     int i = cursor - 1;
-                    E previous = get(i);
+                E previous = list.get(i);
                     cursor = i;
                     return previous;
                 } catch (IndexOutOfBoundsException e) {
                     throw new NoSuchElementException();
                 }

@@ -324,67 +264,70 @@
             public void add(E e) {
                 throw uoe();
             }
         }
 
-        @Override
-        public boolean equals(Object o) {
-            if (o == this) {
-                return true;
-            }
+    static final class SubList<E> extends AbstractImmutableList<E>
+            implements RandomAccess {
 
-            if (!(o instanceof List)) {
-                return false;
-            }
+        @Stable
+        private final List<E> root;
 
-            Iterator<?> oit = ((List<?>) o).iterator();
-            for (int i = 0, s = size(); i < s; i++) {
-                if (!oit.hasNext() || !get(i).equals(oit.next())) {
-                    return false;
-                }
-            }
-            return !oit.hasNext();
-        }
+        @Stable
+        private final int offset;
 
-        @Override
-        public int indexOf(Object o) {
-            Objects.requireNonNull(o);
-            for (int i = 0, s = size(); i < s; i++) {
-                if (o.equals(get(i))) {
-                    return i;
-                }
+        @Stable
+        private final int size;
+
+        private SubList(List<E> root, int offset, int size) {
+            this.root = root;
+            this.offset = offset;
+            this.size = size;
             }
-            return -1;
+
+        /**
+         * Constructs a sublist of another SubList.
+         */
+        static <E> SubList<E> fromSubList(SubList<E> parent, int fromIndex, int toIndex) {
+            return new SubList<E>(parent.root, parent.offset + fromIndex, toIndex - fromIndex);
         }
 
-        @Override
-        public int lastIndexOf(Object o) {
-            Objects.requireNonNull(o);
-            for (int i = size() - 1; i >= 0; i--) {
-                if (o.equals(get(i))) {
-                    return i;
+        /**
+         * Constructs a sublist of an arbitrary AbstractList, which is
+         * not a SubList itself.
+         */
+        static <E> SubList<E> fromList(List<E> list, int fromIndex, int toIndex) {
+            return new SubList<E>(list, fromIndex, toIndex - fromIndex);
                 }
+
+        public E get(int index) {
+            Objects.checkIndex(index, size);
+            return root.get(offset + index);
             }
-            return -1;
+
+        public int size() {
+            return size;
         }
 
-        @Override
-        public int hashCode() {
-            int hash = 1;
-            for (int i = 0, s = size(); i < s; i++) {
-                hash = 31 * hash + get(i).hashCode();
+        public Iterator<E> iterator() {
+            return new ListItr<E>(this, size());
             }
-            return hash;
+
+        public ListIterator<E> listIterator(int index) {
+            rangeCheck(index);
+            return new ListItr<E>(this, size(), index);
         }
 
-        @Override
-        public boolean contains(Object o) {
-            return indexOf(o) >= 0;
+        public List<E> subList(int fromIndex, int toIndex) {
+            subListRangeCheck(fromIndex, toIndex, size);
+            return SubList.fromSubList(this, fromIndex, toIndex);
         }
 
-        IndexOutOfBoundsException outOfBounds(int index) {
-            return new IndexOutOfBoundsException("Index: " + index + " Size: " + size());
+        private void rangeCheck(int index) {
+            if (index < 0 || index > size) {
+                throw outOfBounds(index);
+            }
         }
     }
 
     static final class List12<E> extends AbstractImmutableList<E>
             implements Serializable {

@@ -477,10 +420,37 @@
         }
     }
 
     // ---------- Set Implementations ----------
 
+    static abstract class AbstractImmutableSet<E> extends AbstractImmutableCollection<E>
+            implements Set<E> {
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == this) {
+                return true;
+            } else if (!(o instanceof Set)) {
+                return false;
+            }
+
+            Collection<?> c = (Collection<?>) o;
+            if (c.size() != size()) {
+                return false;
+            }
+            for (Object e : c) {
+                if (e == null || !contains(e)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        @Override
+        public abstract int hashCode();
+    }
+
     @SuppressWarnings("unchecked")
     static <E> Set<E> emptySet() {
         return (Set<E>) SetN.EMPTY_SET;
     }
 
< prev index next >