< 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 >