5-1、java.util.ArrayList
package java.util
;
public class ArrayList< E> extends AbstractList< E>
implements List< E> , RandomAccess , Cloneable , java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L ;
private static final int DEFAULT_CAPACITY = 10 ;
private static final Object[] EMPTY_ELEMENTDATA = {} ;
private transient Object[] elementData ;
private int size ;
public ArrayList( int initialCapacity) {
super() ;
if (initialCapacity < 0)
throw new IllegalArgumentException( "Illegal Capacity: "+ initialCapacity) ;
this. elementData = new Object[initialCapacity] ;
}
public ArrayList() {
super() ;
this. elementData = EMPTY_ELEMENTDATA ;
}
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray() ;
size = elementData. length ;
if ( elementData.getClass() != Object[]. class)
elementData = Arrays. copyOf( elementData , size , Object[]. class) ;
}
public void trimToSize() {
modCount++ ;
if ( size < elementData. length) {
elementData = Arrays. copyOf( elementData , size) ;
}
}
public void ensureCapacity( int minCapacity) {
int minExpand = ( elementData != EMPTY_ELEMENTDATA) ? 0 : DEFAULT_CAPACITY ;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity) ;
}
}
private void ensureCapacityInternal( int minCapacity) {
if ( elementData == EMPTY_ELEMENTDATA) {
minCapacity = Math. max( DEFAULT_CAPACITY , minCapacity) ;
}
ensureExplicitCapacity(minCapacity) ;
}
private void ensureExplicitCapacity( int minCapacity) {
modCount++ ;
if (minCapacity - elementData. length > 0)
grow(minCapacity) ;
}
private static final int MAX_ARRAY_SIZE = Integer. MAX_VALUE - 8 ;
private void grow( int minCapacity) {
int oldCapacity = elementData. length ;
int newCapacity = oldCapacity + (oldCapacity >> 1) ; // 扩容一半容量
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity ;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity) ;
elementData = Arrays. copyOf( elementData , newCapacity) ;
}
private static int hugeCapacity( int minCapacity) {
if (minCapacity < 0)
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 ;}
public boolean contains(Object o) { return indexOf(o) >= 0 ;}
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 ;
}
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 ;
}
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) {
throw new InternalError() ;
}
}
public Object[] toArray() { return Arrays. copyOf( elementData , size) ;}
@SuppressWarnings( "unchecked")
public < T> T[] toArray( T[] a) {
if (a. length < size)
return ( T[]) Arrays. copyOf( elementData , size , a.getClass()) ;
System. arraycopy( elementData , 0 , a , 0 , size) ;
if (a. length > size)
a[ size] = null;
return a ;
}
@SuppressWarnings( "unchecked")
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;
}
public void add( int index , E element) {
rangeCheckForAdd(index) ;
ensureCapacityInternal( size + 1) ; // Increments modCount!!
System. arraycopy( elementData , index , elementData , index + 1 , size - index) ;
elementData[index] = element ;
size++ ;
}
public E remove( int index) {
rangeCheck(index) ;
modCount++ ;
E oldValue = elementData(index) ;
int numMoved = size - index - 1 ;
if (numMoved > 0)
System. arraycopy( elementData , index+ 1 , elementData , index , numMoved) ;
elementData[-- size] = null;
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 void fastRemove( int index) {
modCount++ ;
int numMoved = size - index - 1 ;
if (numMoved > 0)
System. arraycopy( elementData , index+ 1 , elementData , index , numMoved) ;
elementData[-- size] = null; // clear to let GC do its work
}
public void clear() {
modCount++ ;
for ( int i = 0 ; i < size ; i++)
elementData[i] = null;
size = 0 ;
}
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray() ;
int numNew = a. length ;
ensureCapacityInternal( size + numNew) ;
System. arraycopy(a , 0 , elementData , size , numNew) ;
size += numNew ;
return numNew != 0 ;
}
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) ;
int newSize = size - (toIndex-fromIndex) ;
for ( int i = newSize ; i < size ; i++) {
elementData[i] = null;
}
size = newSize ;
}
private void rangeCheck( int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index)) ;
}
private void rangeCheckForAdd( int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index)) ;
}
private String outOfBoundsMsg( int index) { return "Index: "+index+ ", Size: "+ size ;}
public boolean removeAll(Collection<?> c) { return batchRemove(c , false) ;}
public boolean retainAll(Collection<?> c) { return batchRemove(c , true) ;}
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 {
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 ;
}
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
int expectedModCount = modCount ;
s.defaultWriteObject() ;
s.writeInt( size) ;
for ( int i= 0 ; i< size ; i++) {
s.writeObject( elementData[i]) ;
}
if ( modCount != expectedModCount) {
throw new ConcurrentModificationException() ;
}
}
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException , ClassNotFoundException {
elementData = EMPTY_ELEMENTDATA ;
s.defaultReadObject() ;
s.readInt() ;
if ( size > 0) {
ensureCapacityInternal( size) ;
Object[] a = elementData ;
for ( int i= 0 ; i< size ; i++) {
a[i] = s.readObject() ;
}
}
}
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() ;}
private class Itr implements Iterator< E> {
int cursor ; // index of next element to return
int lastRet = - 1 ; // index of last element returned; -1 if no such
int expectedModCount = modCount ;
public boolean hasNext() {
return cursor != size ;
}
@SuppressWarnings( "unchecked")
public E next() {
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() ;
checkForComodification() ;
try {
ArrayList. this.remove( lastRet) ;
cursor = lastRet ;
lastRet = - 1 ;
expectedModCount = modCount ;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException() ;
}
}
final void checkForComodification() {
if ( modCount != expectedModCount)
throw new ConcurrentModificationException() ;
}
}
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 + ")") ;
}
private class SubList extends AbstractList< E> implements RandomAccess {
private final AbstractList< E> parent ;
private final int parentOffset ;
private final int offset ;
int size ;
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() ;
}
}
}
public class ArrayList< E> extends AbstractList< E>
implements List< E> , RandomAccess , Cloneable , java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L ;
private static final int DEFAULT_CAPACITY = 10 ;
private static final Object[] EMPTY_ELEMENTDATA = {} ;
private transient Object[] elementData ;
private int size ;
public ArrayList( int initialCapacity) {
super() ;
if (initialCapacity < 0)
throw new IllegalArgumentException( "Illegal Capacity: "+ initialCapacity) ;
this. elementData = new Object[initialCapacity] ;
}
public ArrayList() {
super() ;
this. elementData = EMPTY_ELEMENTDATA ;
}
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray() ;
size = elementData. length ;
if ( elementData.getClass() != Object[]. class)
elementData = Arrays. copyOf( elementData , size , Object[]. class) ;
}
public void trimToSize() {
modCount++ ;
if ( size < elementData. length) {
elementData = Arrays. copyOf( elementData , size) ;
}
}
public void ensureCapacity( int minCapacity) {
int minExpand = ( elementData != EMPTY_ELEMENTDATA) ? 0 : DEFAULT_CAPACITY ;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity) ;
}
}
private void ensureCapacityInternal( int minCapacity) {
if ( elementData == EMPTY_ELEMENTDATA) {
minCapacity = Math. max( DEFAULT_CAPACITY , minCapacity) ;
}
ensureExplicitCapacity(minCapacity) ;
}
private void ensureExplicitCapacity( int minCapacity) {
modCount++ ;
if (minCapacity - elementData. length > 0)
grow(minCapacity) ;
}
private static final int MAX_ARRAY_SIZE = Integer. MAX_VALUE - 8 ;
private void grow( int minCapacity) {
int oldCapacity = elementData. length ;
int newCapacity = oldCapacity + (oldCapacity >> 1) ; // 扩容一半容量
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity ;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity) ;
elementData = Arrays. copyOf( elementData , newCapacity) ;
}
private static int hugeCapacity( int minCapacity) {
if (minCapacity < 0)
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 ;}
public boolean contains(Object o) { return indexOf(o) >= 0 ;}
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 ;
}
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 ;
}
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) {
throw new InternalError() ;
}
}
public Object[] toArray() { return Arrays. copyOf( elementData , size) ;}
@SuppressWarnings( "unchecked")
public < T> T[] toArray( T[] a) {
if (a. length < size)
return ( T[]) Arrays. copyOf( elementData , size , a.getClass()) ;
System. arraycopy( elementData , 0 , a , 0 , size) ;
if (a. length > size)
a[ size] = null;
return a ;
}
@SuppressWarnings( "unchecked")
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;
}
public void add( int index , E element) {
rangeCheckForAdd(index) ;
ensureCapacityInternal( size + 1) ; // Increments modCount!!
System. arraycopy( elementData , index , elementData , index + 1 , size - index) ;
elementData[index] = element ;
size++ ;
}
public E remove( int index) {
rangeCheck(index) ;
modCount++ ;
E oldValue = elementData(index) ;
int numMoved = size - index - 1 ;
if (numMoved > 0)
System. arraycopy( elementData , index+ 1 , elementData , index , numMoved) ;
elementData[-- size] = null;
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 void fastRemove( int index) {
modCount++ ;
int numMoved = size - index - 1 ;
if (numMoved > 0)
System. arraycopy( elementData , index+ 1 , elementData , index , numMoved) ;
elementData[-- size] = null; // clear to let GC do its work
}
public void clear() {
modCount++ ;
for ( int i = 0 ; i < size ; i++)
elementData[i] = null;
size = 0 ;
}
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray() ;
int numNew = a. length ;
ensureCapacityInternal( size + numNew) ;
System. arraycopy(a , 0 , elementData , size , numNew) ;
size += numNew ;
return numNew != 0 ;
}
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) ;
int newSize = size - (toIndex-fromIndex) ;
for ( int i = newSize ; i < size ; i++) {
elementData[i] = null;
}
size = newSize ;
}
private void rangeCheck( int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index)) ;
}
private void rangeCheckForAdd( int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index)) ;
}
private String outOfBoundsMsg( int index) { return "Index: "+index+ ", Size: "+ size ;}
public boolean removeAll(Collection<?> c) { return batchRemove(c , false) ;}
public boolean retainAll(Collection<?> c) { return batchRemove(c , true) ;}
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 {
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 ;
}
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
int expectedModCount = modCount ;
s.defaultWriteObject() ;
s.writeInt( size) ;
for ( int i= 0 ; i< size ; i++) {
s.writeObject( elementData[i]) ;
}
if ( modCount != expectedModCount) {
throw new ConcurrentModificationException() ;
}
}
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException , ClassNotFoundException {
elementData = EMPTY_ELEMENTDATA ;
s.defaultReadObject() ;
s.readInt() ;
if ( size > 0) {
ensureCapacityInternal( size) ;
Object[] a = elementData ;
for ( int i= 0 ; i< size ; i++) {
a[i] = s.readObject() ;
}
}
}
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() ;}
private class Itr implements Iterator< E> {
int cursor ; // index of next element to return
int lastRet = - 1 ; // index of last element returned; -1 if no such
int expectedModCount = modCount ;
public boolean hasNext() {
return cursor != size ;
}
@SuppressWarnings( "unchecked")
public E next() {
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() ;
checkForComodification() ;
try {
ArrayList. this.remove( lastRet) ;
cursor = lastRet ;
lastRet = - 1 ;
expectedModCount = modCount ;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException() ;
}
}
final void checkForComodification() {
if ( modCount != expectedModCount)
throw new ConcurrentModificationException() ;
}
}
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 + ")") ;
}
private class SubList extends AbstractList< E> implements RandomAccess {
private final AbstractList< E> parent ;
private final int parentOffset ;
private final int offset ;
int size ;
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() ;
}
}
}
//说明:
List 接口的大小可变数组的实现。
实现了所有可选列表操作,并允许包括 null 在内的所有元素。
除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。(此类大致上等同于 Vector 类,除了此类是不同步的。)
size、isEmpty、get、set、iterator 和 listIterator 操作都以固定时间运行。
add 操作以分摊的固定时间 运行,也就是说,添加 n 个元素需要 O(n) 时间。其他所有操作都以线性时间运行(大体上讲)。
与用于 LinkedList 实现的常数因子相比,此实现的常数因子较低。
每个 ArrayList 实例都有一个容量。该容量是指用来存储列表元素的数组的大小。
它总是至少等于列表的大小。随着向 ArrayList 中不断添加元素,其容量也自动增长。
并未指定增长策略的细节,因为这不只是添加元素会带来分摊固定时间开销那样简单。
在添加大量元素前,应用程序可以使用 ensureCapacity 操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。
注意,
此实现不是同步的。
如果多个线程同时访问一个 ArrayList 实例,而其中至少一个线程从结构上修改了列表,那么它必须 保持外部同步。
(结构上的修改是指任何添加或删除一个或多个元素的操作,或者显式调整底层数组的大小;仅仅设置元素的值不是结构上的修改。)
这一般通过对自然封装该列表的对象进行同步操作来完成。
如果不存在这样的对象,则应该使用 Collections.synchronizedList 方法将该列表“包装”起来。
这最好在创建时完成,以防止意外对列表进行不同步的访问:
List list = Collections.synchronizedList(new ArrayList(...));
此类的 iterator 和 listIterator 方法返回的迭代器是快速失败的:
在创建迭代器之后,除非通过迭代器自身的 remove 或 add 方法从结构上对列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出 ConcurrentModificationException。
因此,面对并发的修改,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险。
注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证。
快速失败迭代器会尽最大努力抛出 ConcurrentModificationException。
因此,为提高这类迭代器的正确性而编写一个依赖于此异常的程序是错误的做法:
迭代器的快速失败行为应该仅用于检测 bug。
ArrayList():构造一个初始容量为 10 的空列表。
ArrayList(Collection<? extends E> c): 构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。
ArrayList(int initialCapacity) :构造一个具有指定初始容量的空列表
public void trimToSize():
将此 ArrayList 实例的容量调整为列表的当前大小。应用程序可以使用此操作来最小化 ArrayList 实例的存储量。
public void ensureCapacity(int minCapacity):
如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。
public Object clone():
返回此 ArrayList 实例的浅表副本。(不复制这些元素本身。)
生成一个新的对象,新对象的值和当前对象的值相同,但引用不同。
但是他们的elementData指向同一个引用.