📄 abstractlist.java
字号:
{ checkMod(); if (lastReturned < 0) throw new IllegalStateException(); AbstractList.this.set(lastReturned, o); } public void add(Object o) { checkMod(); AbstractList.this.add(position++, o); size++; lastReturned = -1; knownMod = modCount; } }; } /** * Remove the element at a given position in this list (optional operation). * Shifts all remaining elements to the left to fill the gap. This * implementation always throws an UnsupportedOperationException. * If you want fail-fast iterators, be sure to increment modCount when * overriding this. * * @param index the position within the list of the object to remove * @return the object that was removed * @throws UnsupportedOperationException if this list does not support the * remove operation * @throws IndexOutOfBoundsException if index < 0 || index >= size() * @see #modCount */ public Object remove(int index) { throw new UnsupportedOperationException(); } /** * Remove a subsection of the list. This is called by the clear and * removeRange methods of the class which implements subList, which are * difficult for subclasses to override directly. Therefore, this method * should be overridden instead by the more efficient implementation, if one * exists. Overriding this can reduce quadratic efforts to constant time * in some cases! * <p> * * This implementation first checks for illegal or out of range arguments. It * then obtains a ListIterator over the list using listIterator(fromIndex). * It then calls next() and remove() on this iterator repeatedly, toIndex - * fromIndex times. * * @param fromIndex the index, inclusive, to remove from. * @param toIndex the index, exclusive, to remove to. */ protected void removeRange(int fromIndex, int toIndex) { ListIterator itr = listIterator(fromIndex); for (int index = fromIndex; index < toIndex; index++) { itr.next(); itr.remove(); } } /** * Replace an element of this list with another object (optional operation). * This implementation always throws an UnsupportedOperationException. * * @param index the position within this list of the element to be replaced * @param o the object to replace it with * @return the object that was replaced * @throws UnsupportedOperationException if this list does not support the * set operation * @throws IndexOutOfBoundsException if index < 0 || index >= size() * @throws ClassCastException if o cannot be added to this list due to its * type * @throws IllegalArgumentException if o cannot be added to this list for * some other reason */ public Object set(int index, Object o) { throw new UnsupportedOperationException(); } /** * Obtain a List view of a subsection of this list, from fromIndex * (inclusive) to toIndex (exclusive). If the two indices are equal, the * sublist is empty. The returned list should be modifiable if and only * if this list is modifiable. Changes to the returned list should be * reflected in this list. If this list is structurally modified in * any way other than through the returned list, the result of any subsequent * operations on the returned list is undefined. * <p> * * This implementation returns a subclass of AbstractList. It stores, in * private fields, the offset and size of the sublist, and the expected * modCount of the backing list. If the backing list implements RandomAccess, * the sublist will also. * <p> * * The subclass's <code>set(int, Object)</code>, <code>get(int)</code>, * <code>add(int, Object)</code>, <code>remove(int)</code>, * <code>addAll(int, Collection)</code> and * <code>removeRange(int, int)</code> methods all delegate to the * corresponding methods on the backing abstract list, after * bounds-checking the index and adjusting for the offset. The * <code>addAll(Collection c)</code> method merely returns addAll(size, c). * The <code>listIterator(int)</code> method returns a "wrapper object" * over a list iterator on the backing list, which is created with the * corresponding method on the backing list. The <code>iterator()</code> * method merely returns listIterator(), and the <code>size()</code> method * merely returns the subclass's size field. * <p> * * All methods first check to see if the actual modCount of the backing * list is equal to its expected value, and throw a * ConcurrentModificationException if it is not. * * @param fromIndex the index that the returned list should start from * (inclusive) * @param toIndex the index that the returned list should go to (exclusive) * @return a List backed by a subsection of this list * @throws IndexOutOfBoundsException if fromIndex < 0 * || toIndex > size() * @throws IllegalArgumentException if fromIndex > toIndex * @see ConcurrentModificationException * @see RandomAccess */ public List subList(int fromIndex, int toIndex) { // This follows the specification of AbstractList, but is inconsistent // with the one in List. Don't you love Sun's inconsistencies? if (fromIndex > toIndex) throw new IllegalArgumentException(fromIndex + " > " + toIndex); if (fromIndex < 0 || toIndex > size()) throw new IndexOutOfBoundsException(); if (this instanceof RandomAccess) return new RandomAccessSubList(this, fromIndex, toIndex); return new SubList(this, fromIndex, toIndex); }} // class AbstractList/** * This class follows the implementation requirements set forth in * {@link AbstractList#subList(int, int)}. It matches Sun's implementation * by using a non-public top-level class in the same package. * * @author Original author unknown * @author Eric Blake <ebb9@email.byu.edu> */class SubList extends AbstractList{ // Package visible, for use by iterator. /** The original list. */ final AbstractList backingList; /** The index of the first element of the sublist. */ final int offset; /** The size of the sublist. */ int size; /** * Construct the sublist. * * @param backing the list this comes from * @param fromIndex the lower bound, inclusive * @param toIndex the upper bound, exclusive */ SubList(AbstractList backing, int fromIndex, int toIndex) { backingList = backing; modCount = backing.modCount; offset = fromIndex; size = toIndex - fromIndex; } /** * This method checks the two modCount fields to ensure that there has * not been a concurrent modification, returning if all is okay. * * @throws ConcurrentModificationException if the backing list has been * modified externally to this sublist */ // This can be inlined. Package visible, for use by iterator. void checkMod() { if (modCount != backingList.modCount) throw new ConcurrentModificationException(); } /** * This method checks that a value is between 0 and size (inclusive). If * it is not, an exception is thrown. * * @param index the value to check * @throws IndexOutOfBoundsException if the value is out of range */ // This will get inlined, since it is private. private void checkBoundsInclusive(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException("Index: " + index + ", Size:" + size); } /** * This method checks that a value is between 0 (inclusive) and size * (exclusive). If it is not, an exception is thrown. * * @param index the value to check * @throws IndexOutOfBoundsException if the value is out of range */ // This will get inlined, since it is private. private void checkBoundsExclusive(int index) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException("Index: " + index + ", Size:" + size); } /** * Specified by AbstractList.subList to return the private field size. * * @return the sublist size */ public int size() { checkMod(); return size; } /** * Specified by AbstractList.subList to delegate to the backing list. * * @param index the location to modify * @param o the new value * @return the old value */ public Object set(int index, Object o) { checkMod(); checkBoundsExclusive(index); return backingList.set(index + offset, o); } /** * Specified by AbstractList.subList to delegate to the backing list. * * @param index the location to get from * @return the object at that location */ public Object get(int index) { checkMod(); checkBoundsExclusive(index); return backingList.get(index + offset); } /** * Specified by AbstractList.subList to delegate to the backing list. * * @param index the index to insert at * @param o the object to add */ public void add(int index, Object o) { checkMod(); checkBoundsInclusive(index); backingList.add(index + offset, o); size++; modCount = backingList.modCount; } /** * Specified by AbstractList.subList to delegate to the backing list. * * @param index the index to remove * @return the removed object */ public Object remove(int index) { checkMod(); checkBoundsExclusive(index); Object o = backingList.remove(index + offset); size--; modCount = backingList.modCount; return o; } /** * Specified by AbstractList.subList to delegate to the backing list. * This does no bounds checking, as it assumes it will only be called * by trusted code like clear() which has already checked the bounds. * * @param fromIndex the lower bound, inclusive * @param toIndex the upper bound, exclusive */ protected void removeRange(int fromIndex, int toIndex) { checkMod(); backingList.removeRange(offset + fromIndex, offset + toIndex); size -= toIndex - fromIndex; modCount = backingList.modCount; } /** * Specified by AbstractList.subList to delegate to the backing list. * * @param index the location to insert at * @param c the collection to insert * @return true if this list was modified, in other words, c is non-empty */ public boolean addAll(int index, Collection c) { checkMod(); checkBoundsInclusive(index); int csize = c.size(); boolean result = backingList.addAll(offset + index, c); size += csize; modCount = backingList.modCount; return result; } /** * Specified by AbstractList.subList to return addAll(size, c). * * @param c the collection to insert * @return true if this list was modified, in other words, c is non-empty */ public boolean addAll(Collection c) { return addAll(size, c); } /** * Specified by AbstractList.subList to return listIterator(). * * @return an iterator over the sublist */ public Iterator iterator() { return listIterator(); } /** * Specified by AbstractList.subList to return a wrapper around the * backing list's iterator. * * @param index the start location of the iterator * @return a list iterator over the sublist */ public ListIterator listIterator(final int index) { checkMod(); checkBoundsInclusive(index); return new ListIterator() { private final ListIterator i = backingList.listIterator(index + offset); private int position = index; public boolean hasNext() { checkMod(); return position < size; } public boolean hasPrevious() { checkMod(); return position > 0; } public Object next() { if (position == size) throw new NoSuchElementException(); position++; return i.next(); } public Object previous() { if (position == 0) throw new NoSuchElementException(); position--; return i.previous(); } public int nextIndex() { return i.nextIndex() - offset; } public int previousIndex() { return i.previousIndex() - offset; } public void remove() { i.remove(); size--; position = nextIndex(); modCount = backingList.modCount; } public void set(Object o) { i.set(o); } public void add(Object o) { i.add(o); size++; position++; modCount = backingList.modCount; } // Here is the reason why the various modCount fields are mostly // ignored in this wrapper listIterator. // If the backing listIterator is failfast, then the following holds: // Using any other method on this list will call a corresponding // method on the backing list *after* the backing listIterator // is created, which will in turn cause a ConcurrentModException // when this listIterator comes to use the backing one. So it is // implicitly failfast. // If the backing listIterator is NOT failfast, then the whole of // this list isn't failfast, because the modCount field of the // backing list is not valid. It would still be *possible* to // make the iterator failfast wrt modifications of the sublist // only, but somewhat pointless when the list can be changed under // us. // Either way, no explicit handling of modCount is needed. // However modCount = backingList.modCount must be executed in add // and remove, and size must also be updated in these two methods, // since they do not go through the corresponding methods of the subList. }; }} // class SubList/** * This class is a RandomAccess version of SubList, as required by * {@link AbstractList#subList(int, int)}. * * @author Eric Blake <ebb9@email.byu.edu> */final class RandomAccessSubList extends SubList implements RandomAccess{ /** * Construct the sublist. * * @param backing the list this comes from * @param fromIndex the lower bound, inclusive * @param toIndex the upper bound, exclusive */ RandomAccessSubList(AbstractList backing, int fromIndex, int toIndex) { super(backing, fromIndex, toIndex); }} // class RandomAccessSubList
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -