ArrayList类注释翻译、源码分析
来源:互联网 发布:制作视频的软件 编辑:程序博客网 时间:2024/06/05 13:19
HashMap源码分析 :http://blog.csdn.net/disiwei1012/article/details/73530598
HashSet类注释翻译、fast-fail、源码分析 :http://blog.csdn.net/disiwei1012/article/details/73692452
Hashtable类注释翻译、源码分析 :http://blog.csdn.net/disiwei1012/article/details/73744181
一、类注释翻译
/** * Resizable -array implementation of the <tt> List</tt> interface. Implements * all optional list operations, and permits all elements, including * <tt>null </tt> . In addition to implementing the <tt> List</tt> interface, * this class provides methods to manipulate the size of the array that is * used internally to store the list. (This class is roughly equivalent to * <tt>Vector </tt> , except that it is unsynchronized.)
用“可伸缩数组”来实现List接口。实现了所有List接口中的方法,并且允许存放所有元素,包括Null。
除了实现了List接口,本类还是提供操作数组大小的方法。(本类和Vector类似,只是本类是非同步的)
* <p>The <tt> size</tt> , <tt>isEmpty </tt> , <tt> get </tt>, <tt> set</tt> , * <tt>iterator </tt> , and <tt> listIterator </tt> operations run in constant * time. The <tt> add</tt> operation runs in <i>amortized constant time</i> , * that is, adding n elements requires O(n) time. All of the other operations * run in linear time (roughly speaking). The constant factor is low compared * to that for the <tt> LinkedList</tt> implementation.
size、isEmpty、get、set、iterator、listIterator 这些操作用的时间是常量,(也就是说这些操作与元素的个数无关,操作的时间为o(1))。
add操作花费恒定分摊时间,也就是说插入n的元素的时间为o(n),其实分摊之后,也就相当于插入一个元素的时间为o(1)。
粗略的来说本类的其他操作都能在线性的时间内完成。(也就是说这些操作与元素的个成线性关系,操作的时间复杂度o(n))
What is meant by “Constant Amortized Time” when talking about time complexity of an algorithm?
https://stackoverflow.com/questions/200384/constant-amortized-time
* <p>Each <tt> ArrayList</tt> instance has a <i> capacity</i> . The capacity is * the size of the array used to store the elements in the list. It is always * at least as large as the list size. As elements are added to an ArrayList, * its capacity grows automatically. The details of the growth policy are not * specified beyond the fact that adding an element has constant amortized * time cost.
每个ArrayList实例都有一个容量。这个容量也就是用来存储元素的数组的大小,它至少等于list大小(list大小就是数组实际存放元素的个数)。
当一个元素被添加到集合中,这个集合的容量会自动增长。除了要求添加一个元素的效率为“恒定分摊时间”,对于具体实现的细节没有特别的要求。
* <p>An application can increase the capacity of an <tt> ArrayList</tt> instance * before adding a large number of elements using the <tt> ensureCapacity</tt> * operation. This may reduce the amount of incremental reallocation.
在大批量插入元素前,使用ensureCapacity操作来增加集合的容量。这或许能够减少扩容之后新数组的大小。
【This may reduce the amount of incremental reallocation. 】这句的翻译感觉有点怪怪的。
* <p><strong>Note that this implementation is not synchronized.</strong> * If multiple threads access an <tt> ArrayList</tt> instance concurrently, * and at least one of the threads modifies the list structurally, it * <i>must </i> be synchronized externally. (A structural modification is * any operation that adds or deletes one or more elements, or explicitly * resizes the backing array; merely setting the value of an element is not * a structural modification.) This is typically accomplished by * synchronizing on some object that naturally encapsulates the list.
此类是非同步的。如果多个线程同时操作ArrayList实例,至少一个线程结构性的修改,必须要保证线程的同步。
(结构性修改:增加或删除元素,或者调整数组大小,仅仅修改属性的值不属于结构性修改)
典型的实现是同步操作数组。
* If no such object exists, the list should be "wrapped" using the * {@link Collections#synchronizedList Collections.synchronizedList} * method. This is best done at creation time, to prevent accidental * unsynchronized access to the list: <pre> * List list = Collections.synchronizedList(new ArrayList(...));</pre>
如果这种对象不存在,又想同步集合,可以这样写:
Collections.synchronizedList(new ArrayList(...))
* <p><a name="fail-fast"/> * The iterators returned by this class's {@link #iterator() iterator} and * {@link #listIterator(int) listIterator} methods are <em> fail- fast </em>: * if the list is structurally modified at any time after the iterator is * created, in any way except through the iterator's own * {@link ListIterator#remove() remove} or * {@link ListIterator#add(Object) add} methods, the iterator will throw a * {@link ConcurrentModificationException}. Thus, in the face of * concurrent modification, the iterator fails quickly and cleanly, rather * than risking arbitrary, non - deterministic behavior at an undetermined * time in the future. * <p>Note that the fail - fast behavior of an iterator cannot be guaranteed * as it is, generally speaking, impossible to make any hard guarantees in the * presence of unsynchronized concurrent modification. Fail- fast iterators * throw {@code ConcurrentModificationException} on a best- effort basis. * Therefore, it would be wrong to write a program that depended on this * exception for its correctness: <i> the fail- fast behavior of iterators * should be used only to detect bugs. </i>
关于fail-fast特性的介绍,请参考:http://www.cnblogs.com/skywang12345/p/3308762.html
二、源码分析
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ private static final long serialVersionUID = 8683452581122892189L; /** * 实际用来存储元素的地方,ArrayList的底层数据结构 * 该数组的大小即为ArrayList的容量 */ private transient Object[] elementData ; /** * ArrayList存储元素个数 * */ private int size ; /** * 带初始容量initialCapacity的构造函数 */ public ArrayList( int initialCapacity ) { super (); if (initialCapacity < 0)//如果初始容量小于0,抛出异常 throw new IllegalArgumentException( "Illegal Capacity: "+ initialCapacity ); 创建底层数据,大小为initialCapacity this.elementData = new Object[ initialCapacity]; } /** * 无参构造器,默认容量为10 */ public ArrayList() { this (10); } /** * 创建一个参数为集合对象c的构造函数,将c中的元素添加到ArrayList中 * 通过迭代器返回的顺序和和c中的一样 * @throws 如果c为null,则抛出空指针异常 */ public ArrayList(Collection<? extends E> c ) { elementData = c .toArray(); size = elementData .length ; // c.toArray might (incorrectly) not return Object[] (see 6260652) //toArray有可能不返回Object[],具体参考:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6260652 //如果toArray方法返回的不是Object[],则将elementData转化成Object[], //为ArrayList要能存放任何元素 if (elementData .getClass() != Object[]. class) elementData = Arrays.copyOf( elementData , size , Object[]. class); } /** * 缩短ArrayList容量大小和存储元素的个数相等 */ public void trimToSize() { //修改次数+1 modCount++; int oldCapacity = elementData .length ; if (size < oldCapacity ) {//如果当前数组大小>实际存储的元素个数,则缩小数组的大小 elementData = Arrays.copyOf( elementData , size ); } } /** * 为了确保数组大小大于minCapacity,也就是数组大小大于需要存储的元素个数,增加数组的大小 * @param minCapacity the desired minimum capacity */ public void ensureCapacity( int minCapacity ) { if (minCapacity > 0) //对数组进行扩容 ensureCapacityInternal( minCapacity ); } //数组扩容函数 private void ensureCapacityInternal( int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData .length > 0) grow( minCapacity ); } /** * 数组最大容量限制 */ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; /** * 增加数组容量函数 * @param minCapacity 渴望数组大小 */ private void grow(int minCapacity ) { // overflow-conscious code int oldCapacity = elementData .length ; //新数组大小为原数组的1.5倍 int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity ; if (newCapacity - MAX_ARRAY_SIZE > 0) //如果新数组大小大于数组最大容量限制 newCapacity = hugeCapacity( minCapacity ); // minCapacity is usually close to size, so this is a win: //拷贝数组 elementData = Arrays.copyOf( elementData , newCapacity ); } //如果新数组大小大于数组最大容量限制 private static int hugeCapacity( int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer. MAX_VALUE : MAX_ARRAY_SIZE ; } /** * 获取存储元素个数 */ public int size() { return size ; } /** * 判断是否存储元素 */ public boolean isEmpty() { return size == 0; } /** * 集合中是否包含元素o */ public boolean contains(Object o ) { return indexOf(o ) >= 0; } /** * 返回元素在集合中的位置(初次出现的位置) * 如果集合中不存在该元素,则返回-1,null不能放在equals的左边 */ public int indexOf(Object o ) { if (o == null) { for (int i = 0; i < size ; i ++) if (elementData [i ]== null) return i ; } else { for (int i = 0; i < size ; i ++) if (o .equals(elementData [i ])) return i ; } return -1; } /** * 返回元素在集合中的位置(最后出现的位置) * 如果集合中不存在该元素,则返回-1,null不能放在equals的左边 */ public int lastIndexOf(Object o ) { if (o == null) { for (int i = size -1; i >= 0; i--) if (elementData [i ]== null) return i ; } else { for (int i = size -1; i >= 0; i--) if (o .equals(elementData [i ])) return i ; } return -1; } /** * 浅拷贝一个此ArrayList,并返回 * @return a clone of this <tt> ArrayList </tt> instance */ public Object clone() { try { @SuppressWarnings ("unchecked" ) ArrayList<E> v = (ArrayList<E>) super .clone(); v. elementData = Arrays.copyOf( elementData , size ); v. modCount = 0; return v ; } catch (CloneNotSupportedException e ) { // this shouldn't happen, since we are Cloneable throw new InternalError(); } } /** * 返回一个包含全部元素的数组 */ public Object[] toArray() { return Arrays.copyOf( elementData , size ); } /** * 返回一个指定类型包含全部元素的数组 */ @SuppressWarnings( "unchecked" ) public <T> T[] toArray(T[] a) { if (a .length < size ) // Make a new array of a's runtime type, but my contents: return (T[]) Arrays.copyOf( elementData , size , a .getClass()); System. arraycopy( elementData, 0, a, 0, size); if (a .length > size ) a[ size] = null ; return a ; } //返回数组指定位置上的元素 E elementData( int index) { return (E) elementData [index ]; } /** * 返回数组指定位置上的元素 */ public E get( int index ) { rangeCheck( index); return elementData(index ); } /** * 替换数组指定位置上的元素 */ public E set( int index , E element ) { rangeCheck( index); E oldValue = elementData( index); elementData [index ] = element ; return oldValue ; } /** * 在数组的尾部追加一个元素 */ public boolean add(E e ) { //先判断数组是否需要扩容 ensureCapacityInternal( size + 1); // Increments modCount!! elementData [size ++] = e ; return true ; } /** * Inserts the specified element at the specified position in this * list. Shifts the element currently at that position (if any) and * any subsequent elements to the right (adds one to their indices). * 在指定位置插入元素 */ public void add(int index , E element ) { rangeCheckForAdd( index); //判断元素是否需要扩容 ensureCapacityInternal( size + 1); // Increments modCount!! //System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length) //src:源数组;srcPos:源数组要复制的起始位置;dest:目的数组;destPos:目的数组放置的起始位置;length:复制的长度。 //将元素该位置的元素以及之后的数组全部往后移植一位 System. arraycopy( elementData, index, elementData , index + 1,size - index); elementData [index ] = element ; size++; } /** * Removes the element at the specified position in this list. * Shifts any subsequent elements to the left (subtracts one from their * indices). * 移除指定位置元素 */ public E remove( int index ) { rangeCheck( index); //修改次数+1 modCount++; E oldValue = elementData( index); int numMoved = size - index - 1; if (numMoved > 0) System. arraycopy( elementData, index+1, elementData , index , numMoved); //删除最后一个数组元素的指针,即释放最后一个数组元素指向的对象,让GC能够回收该对象 //关于GC root不熟悉的看下JVM elementData [--size ] = null; // Let gc do its work //返回被移除位置的元素 return oldValue ; } /** * 移除集合中的某个元素,如果集合中不存在该元素,则什么都不做 * 返回是否移除成功 */ public boolean remove(Object o ) { if (o == null) { for (int index = 0; index < size ; index ++) if (elementData [index ] == null) { fastRemove( index); return true ; } } else { for (int index = 0; index < size ; index ++) if (o .equals(elementData [index ])) { fastRemove( index); return true ; } } return false ; } /* * Private remove method that skips bounds checking and does not * return the value removed. * remove(Object o )方法的内部使用方法,私有。 * 此方法相比remove(int index)有何特点? * 没有进行范围判断,即rangeCheck( index);也不返回被删除元素 */ private void fastRemove( int index) { modCount++; int numMoved = size - index - 1; if (numMoved > 0) System. arraycopy( elementData, index+1, elementData , index , numMoved); elementData [--size ] = null; // Let gc do its work } /** * 移除所有元素 */ public void clear() { modCount++; // Let gc do its work for (int i = 0; i < size ; i ++) elementData [i ] = null; size = 0; } /** * 追加集合c中的所有元素到ArrayList集合中,存放的先后顺序保持不变。 / public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a .length ; //判断是否需要增加数组容量 ensureCapacityInternal( size + numNew); // Increments modCount System. arraycopy( a, 0, elementData, size, numNew ); size += numNew; return numNew != 0; } /** * 在执行位置插入集合c中的全部元素 */ public boolean addAll(int index , Collection<? extends E> c ) { rangeCheckForAdd( index); Object[] a = c.toArray(); int numNew = a .length ; ensureCapacityInternal( size + numNew); // Increments modCount int numMoved = size - index ; if (numMoved > 0) System. arraycopy( elementData, index, elementData , index + numNew , numMoved); System. arraycopy( a, 0, elementData, index, numNew ); size += numNew; return numNew != 0; } /** * 移除指定范围内的元素 */ protected void removeRange( int fromIndex, int toIndex ) { modCount++; int numMoved = size - toIndex ; System. arraycopy( elementData, toIndex, elementData , fromIndex , numMoved); // Let gc do its work int newSize = size - (toIndex -fromIndex ); while (size != newSize ) elementData [--size ] = null; } /** * 检测指定位置与元素个数大小,如果指定位置大于存储元素个数,则抛出IndexOutOfBoundsException */ private void rangeCheck( int index) { if (index >= size ) throw new IndexOutOfBoundsException(outOfBoundsMsg(index )); } /** * add and addAll操作判断范围的特有方法 */ private void rangeCheckForAdd( int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException(outOfBoundsMsg(index )); } /** * Constructs an IndexOutOfBoundsException detail message. * Of the many possible refactorings of the error handling code, * this "outlining" performs best with both server and client VMs. */ private String outOfBoundsMsg( int index ) { return "Index: " +index +", Size: " +size ; } /** * 移除与集合c有交集的元素,使用批量移除方法 */ public boolean removeAll(Collection<?> c ) { return batchRemove(c , false); } /** * 保留与集合c有交集的元素,使用批量移除方法 */ public boolean retainAll(Collection<?> c ) { return batchRemove(c , true); }
**下面详细看下批量移除方法:batchRemove。
首先需要明确一点:数组也属于引用数据类型,final Object[] elementData。对于引用类型而言,我们不能改变final修饰的引用的指向,但是我们可以修改指向的具体内容里面的值。就以数组为例:**
public static void main(String[] args) { final String[] s = {"a" ,"b" ,"c" }; //不能修改指向 // s = new String[5]; The final local variable s cannot be assigned. It must be blank and not using a compound assignment System.out.println(Arrays.toString(s)); //虽然不能修改指向,但是我们可以修改指向对象中的内容 s[0] = "d"; s[1] = "e"; s[2] = "f"; System.out.println(Arrays.toString(s)); }输出结果:[a, b, c][d, e, f]
batchRemove定义一个引用指向元素组,然后对原数组中的元素进行操作。
private boolean batchRemove(Collection<?> c , boolean complement ) { final Object[] elementData = this. elementData; int r = 0, w = 0; boolean modified = false; try { for (; r < size ; r ++) if (c .contains( elementData[ r]) == complement ) elementData [w ++] = elementData [r ]; } finally { // Preserve behavioral compatibility with AbstractCollection, // even if c.contains() throws. if (r != size ) { System. arraycopy( elementData, r, elementData , w , size - r); w += size - r; } if (w != size ) { for (int i = w ; i < size ; i ++) elementData [i ] = null; modCount += size - w; size = w; modified = true ; } } return modified ; }
public ListIterator<E> listIterator( int index ) { if (index < 0 || index > size) throw new IndexOutOfBoundsException( "Index: "+ index); return new ListItr( index); } public ListIterator<E> listIterator() { return new ListItr(0); } public Iterator<E> iterator() { return new Itr(); } /** * 实现Iterator接口的迭代器(内部使用) */ private class Itr implements Iterator<E> { int cursor ; // 指向当前元素的下一个元素 int lastRet = -1; // 最后一个返回的元素的位置 int expectedModCount = modCount ; //用来判断是否抛出ConcurrentModificationException //是否还有下一个元素,如果下一个元素的位置小于存储元素数量,返回true,否则false public boolean hasNext() { return cursor != size ; } //返回下一个元素 @SuppressWarnings ("unchecked" ) public E next() { //判断是否抛出ConcurrentModificationException(即fast-fail) checkForComodification(); int i = cursor ; if (i >= size ) throw new NoSuchElementException(); Object[] elementData = ArrayList.this .elementData ; if (i >= elementData .length ) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData [lastRet = i ]; } //移除一个元素 public void remove() { if (lastRet < 0) throw new IllegalStateException(); //判断是否抛出ConcurrentModificationException(即fast-fail) checkForComodification(); try { //移除最后一个返回的元素 ArrayList. this .remove(lastRet ); cursor = lastRet; lastRet = -1; expectedModCount = modCount ; } catch (IndexOutOfBoundsException ex ) { throw new ConcurrentModificationException(); } } //fast-fail具体实现 final void checkForComodification() { if (modCount != expectedModCount ) throw new ConcurrentModificationException(); } } /** * 实现ListIterator接口的迭代器(内部使用) */ private class ListItr extends Itr implements ListIterator<E> { //构造函数 ListItr( int index ) { super (); cursor = index; } //前面是否还有元素 public boolean hasPrevious() { return cursor != 0; } //返回下一个元素位置 public int nextIndex() { return cursor ; } //返回前一个元素位置 public int previousIndex() { return cursor - 1; } //返回前一个元素 @SuppressWarnings ("unchecked" ) public E previous() { checkForComodification(); int i = cursor - 1; if (i < 0) throw new NoSuchElementException(); Object[] elementData = ArrayList.this .elementData ; if (i >= elementData .length ) throw new ConcurrentModificationException(); cursor = i; return (E) elementData [lastRet = i ]; } //设置一个元素 public void set(E e ) { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList. this .set(lastRet , e ); } catch (IndexOutOfBoundsException ex ) { throw new ConcurrentModificationException(); } } //增加一个元素 public void add(E e ) { checkForComodification(); try { int i = cursor ; ArrayList. this .add(i , e ); cursor = i + 1; lastRet = -1; expectedModCount = modCount ; } catch (IndexOutOfBoundsException ex ) { throw new ConcurrentModificationException(); } } } public List<E> subList( int fromIndex , int toIndex) { subListRangeCheck(fromIndex , toIndex , size ); return new SubList( this, 0, 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 + ")"); }//方法返回的List是ArrayList中某段数据的一个视图. 因此, 在操作此方法返回的List时, 同样会改变ArrayList的数据. //对于结构性修改,通过该类修改,不会导致fast-false;但父ArrayList修改会导致该类的fast-false private class SubList extends AbstractList<E> implements RandomAccess { private final AbstractList<E> parent; private final int parentOffset; private final int offset; int size ; //parent 父类型 //offset 父类型的偏移量 //fromIndex 子列表的开始元素,位于父列表的位置 //toIndex 子列表的结束元素,位于父列表的位置 SubList(AbstractList<E> parent, int offset , int fromIndex, int toIndex) { this .parent = parent ; this .parentOffset = fromIndex ; this .offset = offset + fromIndex ; this .size = toIndex - fromIndex ; this .modCount = ArrayList. this. modCount; } public E set(int index , E e ) { rangeCheck( index); checkForComodification(); E oldValue = ArrayList.this .elementData(offset + index ); ArrayList. this .elementData [offset + index ] = e ; return oldValue ; } public E get(int index ) { rangeCheck( index); checkForComodification(); return ArrayList. this.elementData( offset + index ); } public int size() { checkForComodification(); return this .size ; } public void add( int index, E e) { rangeCheckForAdd( index); checkForComodification(); parent.add( parentOffset + index , e ); this .modCount = parent .modCount ; this .size ++; } public E remove( int index) { rangeCheck( index); checkForComodification(); E result = parent.remove( parentOffset + index ); this .modCount = parent .modCount ; this .size --; return result ; } protected void removeRange( int fromIndex, int toIndex ) { checkForComodification(); parent.removeRange( parentOffset + fromIndex , parentOffset + toIndex ); this .modCount = parent .modCount ; this .size -= toIndex - fromIndex ; } public boolean addAll(Collection<? extends E> c) { return addAll(this .size , c ); } public boolean addAll( int index, Collection<? extends E> c ) { rangeCheckForAdd( index); int cSize = c .size(); if (cSize ==0) return false ; checkForComodification(); parent.addAll( parentOffset + index , c ); this .modCount = parent .modCount ; this .size += cSize ; return true ; } public Iterator<E> iterator() { return listIterator(); } public ListIterator<E> listIterator( final int index ) { checkForComodification(); rangeCheckForAdd( index); final int offset = this. offset; return new ListIterator<E>() { int cursor = index ; int lastRet = -1; int expectedModCount = ArrayList.this .modCount ; public boolean hasNext() { return cursor != SubList. this. size; } @SuppressWarnings ("unchecked" ) public E next() { checkForComodification(); int i = cursor ; if (i >= SubList. this. size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this .elementData ; if (offset + i >= elementData .length ) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData [offset + (lastRet = i )]; } public boolean hasPrevious() { return cursor != 0; } @SuppressWarnings ("unchecked" ) public E previous() { checkForComodification(); int i = cursor - 1; if (i < 0) throw new NoSuchElementException(); Object[] elementData = ArrayList.this .elementData ; if (offset + i >= elementData .length ) throw new ConcurrentModificationException(); cursor = i; return (E) elementData [offset + (lastRet = i )]; } public int nextIndex() { return cursor ; } public int previousIndex() { return cursor - 1; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { SubList. this .remove(lastRet ); cursor = lastRet; lastRet = -1; expectedModCount = ArrayList.this .modCount ; } catch (IndexOutOfBoundsException ex ) { throw new ConcurrentModificationException(); } } public void set(E e ) { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList. this .set(offset + lastRet , e ); } catch (IndexOutOfBoundsException ex ) { throw new ConcurrentModificationException(); } } public void add(E e ) { checkForComodification(); try { int i = cursor ; SubList. this .add(i , e ); cursor = i + 1; lastRet = -1; expectedModCount = ArrayList.this .modCount ; } catch (IndexOutOfBoundsException ex ) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (expectedModCount != ArrayList.this .modCount ) throw new ConcurrentModificationException(); } }; } public List<E> subList( int fromIndex, int toIndex ) { subListRangeCheck( fromIndex, toIndex, size); return new SubList( this, offset, fromIndex , toIndex ); } private void rangeCheck( int index) { if (index < 0 || index >= this .size ) throw new IndexOutOfBoundsException(outOfBoundsMsg(index )); } private void rangeCheckForAdd( int index) { if (index < 0 || index > this. size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index )); } private String outOfBoundsMsg( int index) { return "Index: " +index +", Size: " + this. size; } private void checkForComodification() { if (ArrayList. this. modCount != this .modCount ) throw new ConcurrentModificationException(); } }}
- ArrayList类注释翻译、源码分析
- Hashtable类注释翻译、源码分析
- LinkedList类注释翻译、源码分析
- HashSet类注释翻译、fast-fail、源码分析
- tasklet源码注释翻译
- 集合类学习之Arraylist 源码分析
- 集合类学习之Arraylist 源码分析
- java集合类源码分析 ArrayList
- Java源码分析之ArrayList类
- 【Java集合类源码分析】ArrayList源码分析
- ArrayList源码分析
- ArrayList源码分析
- ArrayList 源码分析
- ArrayList源码分析
- ArrayList LinkedList 源码分析
- ArrayList,LinkedList源码分析
- 源码分析之ArrayList
- ArrayList 源码分析
- IDT系列:(一)初探IDT,Interrupt Descriptor Table,中断描述符表
- MATLAB相关分析
- 在maven web项目中配置log4j打印日志及Mybatis sql语句
- 实现非递归二分法查询
- Missing Number
- ArrayList类注释翻译、源码分析
- 隔个取马
- datatables排序时传入xml参数问题
- Android系统和Linux系统的对比
- 优化算法——遗传算法(好复杂)
- busybox简介
- Maven项目转为jar包运行
- JavaWeb学习篇之----Servlet过滤器Filter和监听器
- 【Question 01】关于 intellij 启动 web 项目控制台乱码的问题