< 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,84 **** */ 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(); } --- 68,77 ----
*** 86,120 **** @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; ! } ! @Override ! public abstract int hashCode(); } static abstract class AbstractImmutableList<E> extends AbstractImmutableCollection<E> implements List<E>, RandomAccess { --- 79,93 ---- @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(); } } ! // ---------- List Implementations ---------- ! @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,309 **** @Override public List<E> subList(int fromIndex, int toIndex) { int size = size(); subListRangeCheck(fromIndex, toIndex, size); ! return new SubList<E>(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; } ! public E get(int index) { ! Objects.checkIndex(index, size); ! return root.get(offset + index); } ! public int size() { ! return size; } ! public Iterator<E> iterator() { ! return listIterator(); } ! ! public ListIterator<E> listIterator(int index) { ! rangeCheck(index); ! ! ListIterator<E> i = root.listIterator(offset + index); ! ! return new ListIterator<>() { ! ! public boolean hasNext() { ! return nextIndex() < size; } ! public E next() { ! if (hasNext()) { ! return i.next(); ! } else { ! throw new NoSuchElementException(); ! } } ! public boolean hasPrevious() { ! return previousIndex() >= 0; } ! public E previous() { ! if (hasPrevious()) { ! return i.previous(); ! } else { ! throw new NoSuchElementException(); } } ! ! public int nextIndex() { ! return i.nextIndex() - offset; } ! public int previousIndex() { ! return i.previousIndex() - offset; } - - 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); } ! private void rangeCheck(int index) { ! if (index < 0 || index > size) { ! throw outOfBounds(index); ! } } } ! ! 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 + ")"); } @Override ! public Iterator<E> iterator() { ! return new Itr(size()); } @Override ! public ListIterator<E> listIterator() { ! return listIterator(0); } ! @Override ! public ListIterator<E> listIterator(final int index) { ! int size = size(); ! if (index < 0 || index > size) { ! throw outOfBounds(index); } - return new ListItr(index, size); } ! private class Itr implements Iterator<E> { ! int cursor; private final int size; ! Itr(int size) { this.size = size; } public boolean hasNext() { return cursor != size; } public E next() { try { int i = cursor; ! E next = 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); cursor = i; return previous; } catch (IndexOutOfBoundsException e) { throw new NoSuchElementException(); } --- 101,249 ---- @Override public List<E> subList(int fromIndex, int toIndex) { int size = size(); subListRangeCheck(fromIndex, toIndex, size); ! return SubList.fromList(this, fromIndex, toIndex); } ! 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 + ")"); } ! @Override ! public Iterator<E> iterator() { ! return new ListItr<E>(this, size()); } ! @Override ! public ListIterator<E> listIterator() { ! return listIterator(0); } ! @Override ! public ListIterator<E> listIterator(final int index) { ! int size = size(); ! if (index < 0 || index > size) { ! throw outOfBounds(index); } ! return new ListItr<E>(this, size, index); } ! @Override ! public boolean equals(Object o) { ! if (o == this) { ! return true; } ! if (!(o instanceof List)) { ! return false; } ! 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(); } ! @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; } } ! return -1; } ! @Override ! public int lastIndexOf(Object o) { ! Objects.requireNonNull(o); ! for (int i = size() - 1; i >= 0; i--) { ! if (o.equals(get(i))) { ! return i; } } ! return -1; } @Override ! 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 boolean contains(Object o) { ! return indexOf(o) >= 0; } ! IndexOutOfBoundsException outOfBounds(int index) { ! return new IndexOutOfBoundsException("Index: " + index + " Size: " + size()); } } ! static final class ListItr<E> implements ListIterator<E> { ! @Stable ! private final List<E> list; + @Stable private final 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 = list.get(i); cursor = i + 1; return next; } catch (IndexOutOfBoundsException e) { throw new NoSuchElementException(); } } public void remove() { throw uoe(); } public boolean hasPrevious() { return cursor != 0; } public E previous() { try { int i = cursor - 1; ! E previous = list.get(i); cursor = i; return previous; } catch (IndexOutOfBoundsException e) { throw new NoSuchElementException(); }
*** 324,390 **** public void add(E e) { throw uoe(); } } ! @Override ! public boolean equals(Object o) { ! if (o == this) { ! return true; ! } ! if (!(o instanceof List)) { ! return false; ! } ! 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(); ! } ! @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; ! } } ! return -1; } ! @Override ! public int lastIndexOf(Object o) { ! Objects.requireNonNull(o); ! for (int i = size() - 1; i >= 0; i--) { ! if (o.equals(get(i))) { ! return i; } } ! return -1; } ! @Override ! 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 boolean contains(Object o) { ! return indexOf(o) >= 0; } ! IndexOutOfBoundsException outOfBounds(int index) { ! return new IndexOutOfBoundsException("Index: " + index + " Size: " + size()); } } static final class List12<E> extends AbstractImmutableList<E> implements Serializable { --- 264,333 ---- public void add(E e) { throw uoe(); } } ! static final class SubList<E> extends AbstractImmutableList<E> ! implements RandomAccess { ! @Stable ! private final List<E> root; ! @Stable ! private final int offset; ! @Stable ! private final int size; ! ! private SubList(List<E> root, int offset, int size) { ! this.root = root; ! this.offset = offset; ! this.size = size; } ! ! /** ! * 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); } ! /** ! * 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); } ! ! public int size() { ! return size; } ! public Iterator<E> iterator() { ! return new ListItr<E>(this, size()); } ! ! public ListIterator<E> listIterator(int index) { ! rangeCheck(index); ! return new ListItr<E>(this, size(), index); } ! public List<E> subList(int fromIndex, int toIndex) { ! subListRangeCheck(fromIndex, toIndex, size); ! return SubList.fromSubList(this, fromIndex, toIndex); } ! private void rangeCheck(int index) { ! if (index < 0 || index > size) { ! throw outOfBounds(index); ! } } } static final class List12<E> extends AbstractImmutableList<E> implements Serializable {
*** 477,486 **** --- 420,456 ---- } } // ---------- 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 >