--- old/src/java.base/share/classes/java/util/ImmutableCollections.java 2018-03-22 16:29:07.023948443 +0100 +++ new/src/java.base/share/classes/java/util/ImmutableCollections.java 2018-03-22 16:29:06.531946003 +0100 @@ -70,13 +70,6 @@ static UnsupportedOperationException uoe() { return new UnsupportedOperationException(); } - // ---------- List Implementations ---------- - - @SuppressWarnings("unchecked") - static List emptyList() { - return (List) ListN.EMPTY_LIST; - } - static abstract class AbstractImmutableCollection extends AbstractCollection { // all mutating methods throw UnsupportedOperationException @Override public boolean add(E e) { throw uoe(); } @@ -88,31 +81,11 @@ @Override public boolean retainAll(Collection c) { throw uoe(); } } - static abstract class AbstractImmutableSet extends AbstractImmutableCollection - implements Set { - - @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 List emptyList() { + return (List) ListN.EMPTY_LIST; } static abstract class AbstractImmutableList extends AbstractImmutableCollection @@ -130,102 +103,7 @@ public List subList(int fromIndex, int toIndex) { int size = size(); subListRangeCheck(fromIndex, toIndex, size); - return new SubList(this, fromIndex, toIndex); - } - - private static final class SubList extends AbstractImmutableList - implements RandomAccess { - private final List root; - final int offset; - int size; - - /** - * Constructs a sublist of an arbitrary AbstractList, which is - * not a SubList itself. - */ - SubList(List root, int fromIndex, int toIndex) { - this.root = root; - this.offset = fromIndex; - this.size = toIndex - fromIndex; - } - - /** - * Constructs a sublist of another SubList. - */ - SubList(SubList 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 iterator() { - return listIterator(); - } - - public ListIterator listIterator(int index) { - rangeCheck(index); - - ListIterator 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 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); - } - } + return SubList.fromList(this, fromIndex, toIndex); } static void subListRangeCheck(int fromIndex, int toIndex, int size) { @@ -240,7 +118,7 @@ @Override public Iterator iterator() { - return new Itr(size()); + return new ListItr(this, size()); } @Override @@ -254,76 +132,7 @@ if (index < 0 || index > size) { throw outOfBounds(index); } - return new ListItr(index, size); - } - - private class Itr implements Iterator { - - 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 { - - 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(); - } - } - - public int nextIndex() { - return cursor; - } - - public int previousIndex() { - return cursor - 1; - } - - public void set(E e) { - throw uoe(); - } - - public void add(E e) { - throw uoe(); - } + return new ListItr(this, size, index); } @Override @@ -386,6 +195,140 @@ } } + static final class ListItr implements ListIterator { + + @Stable + private final List list; + + @Stable + private final int size; + + private int cursor; + + ListItr(List list, int size) { + this(list, size, 0); + } + + ListItr(List 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(); + } + } + + public int nextIndex() { + return cursor; + } + + public int previousIndex() { + return cursor - 1; + } + + public void set(E e) { + throw uoe(); + } + + public void add(E e) { + throw uoe(); + } + } + + static final class SubList extends AbstractImmutableList + implements RandomAccess { + + @Stable + private final List root; + + @Stable + private final int offset; + + @Stable + private final int size; + + private SubList(List root, int offset, int size) { + this.root = root; + this.offset = offset; + this.size = size; + } + + /** + * Constructs a sublist of another SubList. + */ + static SubList fromSubList(SubList parent, int fromIndex, int toIndex) { + return new SubList(parent.root, parent.offset + fromIndex, toIndex - fromIndex); + } + + /** + * Constructs a sublist of an arbitrary AbstractList, which is + * not a SubList itself. + */ + static SubList fromList(List list, int fromIndex, int toIndex) { + return new SubList(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 iterator() { + return new ListItr(this, size()); + } + + public ListIterator listIterator(int index) { + rangeCheck(index); + return new ListItr(this, size(), index); + } + + public List 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 extends AbstractImmutableList implements Serializable { @@ -479,6 +422,33 @@ // ---------- Set Implementations ---------- + static abstract class AbstractImmutableSet extends AbstractImmutableCollection + implements Set { + + @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 Set emptySet() { return (Set) SetN.EMPTY_SET;