- [ArrayListç®ä»](#arraylistç®ä»)
- [ArrayListæ ¸å¿æºç ](#arraylistæ ¸å¿æºç )
- [ArrayListæºç åæ](#arraylistæºç åæ)
- [System.arraycopy\(\)åArrays.copyOf\(\)æ¹æ³](#systemarraycopyåarrayscopyofæ¹æ³)
- [两è
èç³»ä¸åºå«](#两è
èç³»ä¸åºå«)
- [ArrayListæ ¸å¿æ©å®¹ææ¯](#arraylistæ ¸å¿æ©å®¹ææ¯)
- [å
é¨ç±»](#å
é¨ç±»)
- [ArrayListç»å
¸Demo](#arraylistç»å
¸demo)
### ArrayListç®ä»
ããArrayList çåºå±æ¯æ°ç»éåï¼ç¸å½äºå¨ææ°ç»ãä¸ Java ä¸çæ°ç»ç¸æ¯ï¼å®ç容éè½å¨æå¢é¿ã卿·»å 大éå
ç´ åï¼åºç¨ç¨åºå¯ä»¥ä½¿ç¨`ensureCapacity`æä½æ¥å¢å ArrayList å®ä¾ç容éãè¿å¯ä»¥åå°éå¢å¼ååé
çæ°éã
å®ç»§æ¿äº **AbstractList**ï¼å®ç°äº **List**, **RandomAccess**, **Cloneable**, **java.io.Serializable** è¿äºæ¥å£ã
卿们妿°æ®ç»æçæ¶åå°±ç¥éäºçº¿æ§è¡¨ç顺åºåå¨ï¼æå
¥å é¤å
ç´ çæ¶é´å¤æåº¦ä¸º**Oï¼nï¼**,æ±è¡¨é¿ä»¥åå¢å å
ç´ ï¼å第 i å
ç´ çæ¶é´å¤æåº¦ä¸º**Oï¼1ï¼**
ã ArrayList ç»§æ¿äºAbstractListï¼å®ç°äºListã宿¯ä¸ä¸ªæ°ç»éåï¼æä¾äºç¸å
³çæ·»å ãå é¤ãä¿®æ¹ãéåçåè½ã
ããArrayList å®ç°äº**RandomAccess æ¥å£**ï¼ RandomAccess æ¯ä¸ä¸ªæ å¿æ¥å£ï¼è¡¨æå®ç°è¿ä¸ªè¿ä¸ªæ¥å£ç List éåæ¯æ¯æ**å¿«ééæºè®¿é®**çãå¨ ArrayList ä¸ï¼æä»¬å³å¯ä»¥éè¿å
ç´ çåºå·å¿«éè·åå
ç´ å¯¹è±¡ï¼è¿å°±æ¯å¿«ééæºè®¿é®ã
ããArrayList å®ç°äº**Cloneable æ¥å£**ï¼å³è¦çäºå½æ° clone()ï¼**è½è¢«å
é**ã
ããArrayList å®ç°**java.io.Serializable æ¥å£**ï¼è¿æå³çArrayList**æ¯æåºåå**ï¼**è½éè¿åºååå»ä¼ è¾**ã
ããå Vector ä¸åï¼**ArrayList ä¸çæä½ä¸æ¯çº¿ç¨å®å
¨ç**ï¼æä»¥ï¼å»ºè®®å¨å线ç¨ä¸æä½¿ç¨ ArrayListï¼èå¨å¤çº¿ç¨ä¸å¯ä»¥éæ© Vector æè
CopyOnWriteArrayListã
### ArrayListæ ¸å¿æºç
```java
package java.util;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
public class ArrayList extends AbstractList
implements List, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
/**
* é»è®¤åå§å®¹é大å°
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 空æ°ç»ï¼ç¨äºç©ºå®ä¾ï¼ã
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
//ç¨äºé»è®¤å¤§å°ç©ºå®ä¾çå
±äº«ç©ºæ°ç»å®ä¾ã
//æä»¬æå®ä»EMPTY_ELEMENTDATAæ°ç»ä¸åºååºæ¥ï¼ä»¥ç¥é卿·»å 第ä¸ä¸ªå
ç´ æ¶å®¹ééè¦å¢å å¤å°ã
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* ä¿åArrayListæ°æ®çæ°ç»
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* ArrayList æå
å«çå
ç´ ä¸ªæ°
*/
private int size;
/**
* 带åå§å®¹éåæ°çæé 彿°ãï¼ç¨æ·èªå·±æå®å®¹éï¼
*/
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
//å建initialCapacity大å°çæ°ç»
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
//å建空æ°ç»
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
/**
*é»è®¤æé 彿°ï¼DEFAULTCAPACITY_EMPTY_ELEMENTDATA 为0.åå§å为10ï¼ä¹å°±æ¯è¯´åå§å
¶å®æ¯ç©ºæ°ç» 彿·»å 第ä¸ä¸ªå
ç´ çæ¶åæ°ç»å®¹éæåæ10
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* æé ä¸ä¸ªå
嫿å®éåçå
ç´ çåè¡¨ï¼æç
§å®ä»¬ç±éåçè¿ä»£å¨è¿åç顺åºã
*/
public ArrayList(Collection extends E> c) {
//
elementData = c.toArray();
//妿æå®éåå
ç´ ä¸ªæ°ä¸ä¸º0
if ((size = elementData.length) != 0) {
// c.toArray å¯è½è¿åç䏿¯Objectç±»åçæ°ç»æä»¥å ä¸ä¸é¢çè¯å¥ç¨äºå¤æï¼
//è¿éç¨å°äºåå°éé¢çgetClass()æ¹æ³
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// ç¨ç©ºæ°ç»ä»£æ¿
this.elementData = EMPTY_ELEMENTDATA;
}
}
/**
* ä¿®æ¹è¿ä¸ªArrayListå®ä¾ç容鿝å表çå½å大å°ã åºç¨ç¨åºå¯ä»¥ä½¿ç¨æ¤æä½æ¥æå°åArrayListå®ä¾çåå¨ã
*/
public void trimToSize() {
modCount++;
if (size < elementData.length) {
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
//ä¸é¢æ¯ArrayListçæ©å®¹æºå¶
//ArrayListçæ©å®¹æºå¶æé«äºæ§è½ï¼å¦ææ¯æ¬¡åªæ©å
ä¸ä¸ªï¼
//é£ä¹é¢ç¹çæå
¥ä¼å¯¼è´é¢ç¹çæ·è´ï¼é使§è½ï¼èArrayListçæ©å®¹æºå¶é¿å
äºè¿ç§æ
åµã
/**
* 妿å¿
è¦ï¼å¢å æ¤ArrayListå®ä¾ç容éï¼ä»¥ç¡®ä¿å®è³å°è½å®¹çº³å
ç´ çæ°é
* @param minCapacity æéçæå°å®¹é
*/
public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
// any size if not default element table
? 0
// larger than default for default empty table. It's already
// supposed to be at default size.
: DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
//å¾å°æå°æ©å®¹é
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
// è·åé»è®¤ç容éåä¼ å
¥åæ°çè¾å¤§å¼
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
//夿æ¯å¦éè¦æ©å®¹
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
//è°ç¨growæ¹æ³è¿è¡æ©å®¹ï¼è°ç¨æ¤æ¹æ³ä»£è¡¨å·²ç»å¼å§æ©å®¹äº
grow(minCapacity);
}
/**
* è¦åé
çæå¤§æ°ç»å¤§å°
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* ArrayListæ©å®¹çæ ¸å¿æ¹æ³ã
*/
private void grow(int minCapacity) {
// oldCapacity为æ§å®¹éï¼newCapacity为æ°å®¹é
int oldCapacity = elementData.length;
//å°oldCapacity å³ç§»ä¸ä½ï¼å
¶ææç¸å½äºoldCapacity /2ï¼
//æä»¬ç¥éä½è¿ç®çé度è¿è¿å¿«äºæ´é¤è¿ç®ï¼æ´å¥è¿ç®å¼çç»æå°±æ¯å°æ°å®¹éæ´æ°ä¸ºæ§å®¹éç1.5åï¼
int newCapacity = oldCapacity + (oldCapacity >> 1);
//ç¶åæ£æ¥æ°å®¹éæ¯å¦å¤§äºæå°éè¦å®¹éï¼è¥è¿æ¯å°äºæå°éè¦å®¹éï¼é£ä¹å°±ææå°éè¦å®¹éå½ä½æ°ç»çæ°å®¹éï¼
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//åæ£æ¥æ°å®¹éæ¯å¦è¶
åºäºArrayListæå®ä¹çæå¤§å®¹éï¼
//è¥è¶
åºäºï¼åè°ç¨hugeCapacity()æ¥æ¯è¾minCapacityå MAX_ARRAY_SIZEï¼
//妿minCapacity大äºMAX_ARRAY_SIZEï¼åæ°å®¹éå为Interger.MAX_VALUEï¼å¦åï¼æ°å®¹é大å°å为 MAX_ARRAY_SIZEã
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);
}
//æ¯è¾minCapacityå MAX_ARRAY_SIZE
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;
}
/**
* 妿æ¤å表ä¸å
å«å
ç´ ï¼åè¿å true ã
*/
public boolean isEmpty() {
//注æ=å==çåºå«
return size == 0;
}
/**
* 妿æ¤å表å
嫿å®çå
ç´ ï¼åè¿åtrue ã
*/
public boolean contains(Object o) {
//indexOf()æ¹æ³ï¼è¿åæ¤åè¡¨ä¸æå®å
ç´ ç馿¬¡åºç°çç´¢å¼ï¼å¦ææ¤å表ä¸å
嫿¤å
ç´ ï¼å为-1
return indexOf(o) >= 0;
}
/**
*è¿åæ¤åè¡¨ä¸æå®å
ç´ ç馿¬¡åºç°çç´¢å¼ï¼å¦ææ¤å表ä¸å
嫿¤å
ç´ ï¼å为-1
*/
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++)
//equals()æ¹æ³æ¯è¾
if (o.equals(elementData[i]))
return i;
}
return -1;
}
/**
* è¿åæ¤åè¡¨ä¸æå®å
ç´ çæå䏿¬¡åºç°çç´¢å¼ï¼å¦ææ¤å表ä¸å
å«å
ç´ ï¼åè¿å-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;
}
/**
* è¿åæ¤ArrayListå®ä¾çæµ
æ·è´ã ï¼å
ç´ æ¬èº«ä¸è¢«å¤å¶ãï¼
*/
public Object clone() {
try {
ArrayList> v = (ArrayList>) super.clone();
//Arrays.copyOfåè½æ¯å®ç°æ°ç»çå¤å¶ï¼è¿åå¤å¶åçæ°ç»ãåæ°æ¯è¢«å¤å¶çæ°ç»åå¤å¶çé¿åº¦
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// è¿ä¸åºè¯¥åçï¼å 为æä»¬æ¯å¯ä»¥å
éç
throw new InternalError(e);
}
}
/**
*以æ£ç¡®ç顺åºï¼ä»ç¬¬ä¸ä¸ªå°æåä¸ä¸ªå
ç´ ï¼è¿åä¸ä¸ªå
嫿¤åè¡¨ä¸ææå
ç´ çæ°ç»ã
*è¿åçæ°ç»å°æ¯âå®å
¨çâï¼å 为该å表ä¸ä¿ç对å®çå¼ç¨ã ï¼æ¢å¥è¯è¯´ï¼è¿ä¸ªæ¹æ³å¿
é¡»åé
ä¸ä¸ªæ°çæ°ç»ï¼ã
*å æ¤ï¼è°ç¨è
å¯ä»¥èªç±å°ä¿®æ¹è¿åçæ°ç»ã æ¤æ¹æ³å
å½åºäºéµåååºäºéåçAPIä¹é´çæ¡¥æ¢ã
*/
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
/**
* 以æ£ç¡®ç顺åºè¿åä¸ä¸ªå
嫿¤åè¡¨ä¸ææå
ç´ çæ°ç»ï¼ä»ç¬¬ä¸ä¸ªå°æåä¸ä¸ªå
ç´ ï¼;
*è¿åçæ°ç»çè¿è¡æ¶ç±»åæ¯æå®æ°ç»çè¿è¡æ¶ç±»åã 妿å表éåæå®çæ°ç»ï¼åè¿åå
¶ä¸ã
*å¦åï¼å°ä¸ºæå®æ°ç»çè¿è¡æ¶ç±»å忤å表ç大å°åé
ä¸ä¸ªæ°æ°ç»ã
*妿å表éç¨äºæå®çæ°ç»ï¼å
¶ä½ç©ºé´ï¼å³æ°ç»çå表æ°éå¤äºæ¤å
ç´ ï¼ï¼åç´§è·å¨éåç»æåçæ°ç»ä¸çå
ç´ è®¾ç½®ä¸ºnull ã
*ï¼è¿ä»
å¨è°ç¨è
ç¥éå表ä¸å
å«ä»»ä½ç©ºå
ç´ çæ
åµä¸æè½ç¡®å®å表çé¿åº¦ãï¼
*/
@SuppressWarnings("unchecked")
public T[] toArray(T[] a) {
if (a.length < size)
// æ°å»ºä¸ä¸ªè¿è¡æ¶ç±»åçæ°ç»ï¼ä½æ¯ArrayListæ°ç»çå
容
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
//è°ç¨Systemæä¾çarraycopy()æ¹æ³å®ç°æ°ç»ä¹é´çå¤å¶
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
// Positional Access Operations
@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) {
//对indexè¿è¡ç鿣æ¥
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
//è¿å忥å¨è¿ä¸ªä½ç½®çå
ç´
return oldValue;
}
/**
* å°æå®çå
ç´ è¿½å å°æ¤åè¡¨çæ«å°¾ã
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
//è¿éçå°ArrayListæ·»å å
ç´ çå®è´¨å°±ç¸å½äºä¸ºæ°ç»èµå¼
elementData[size++] = e;
return true;
}
/**
* 卿¤å表ä¸çæå®ä½ç½®æå
¥æå®çå
ç´ ã
*å
è°ç¨ rangeCheckForAdd 对indexè¿è¡ç鿣æ¥ï¼ç¶åè°ç¨ ensureCapacityInternal æ¹æ³ä¿è¯capacityè¶³å¤å¤§ï¼
*åå°ä»indexå¼å§ä¹åçæææååç§»ä¸ä¸ªä½ç½®ï¼å°elementæå
¥indexä½ç½®ï¼æåsizeå 1ã
*/
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
//arraycopy()è¿ä¸ªå®ç°æ°ç»ä¹é´å¤å¶çæ¹æ³ä¸å®è¦çä¸ä¸ï¼ä¸é¢å°±ç¨å°äºarraycopy()æ¹æ³å®ç°æ°ç»èªå·±å¤å¶èªå·±
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; // clear to let GC do its work
//ä»å表ä¸å é¤çå
ç´
return oldValue;
}
/**
* ä»å表ä¸å 餿å®å
ç´ ç第ä¸ä¸ªåºç°ï¼å¦æåå¨ï¼ã 妿å表ä¸å
å«è¯¥å
ç´ ï¼åå®ä¸ä¼æ´æ¹ã
*è¿åtrueï¼å¦ææ¤å表å
嫿å®çå
ç´
*/
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.
*/
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++;
// ææ°ç»ä¸ææçå
ç´ çå¼è®¾ä¸ºnull
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
/**
* ææå®éåçIteratorè¿åç顺åºå°æå®éåä¸çææå
ç´ è¿½å å°æ¤åè¡¨çæ«å°¾ã
*/
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;
}
/**
* å°æå®éåä¸çææå
ç´ æå
¥å°æ¤å表ä¸ï¼ä»æå®çä½ç½®å¼å§ã
*/
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;
}
/**
* 仿¤å表ä¸å 餿æç´¢å¼ä¸ºfromIndex ï¼å«ï¼åtoIndexä¹é´çå
ç´ ã
*å°ä»»ä½åç»å
ç´ ç§»å¨å°å·¦ä¾§ï¼åå°å
¶ç´¢å¼ï¼ã
*/
protected void removeRange(int fromIndex, int toIndex) {
modCount++;
int numMoved = size - toIndex;
System.arraycopy(elementData, toIndex, elementData, fromIndex,
numMoved);
// clear to let GC do its work
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));
}
/**
* addåaddAll使ç¨çrangeCheckçä¸ä¸ªçæ¬
*/
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
/**
* è¿åIndexOutOfBoundsExceptionç»èä¿¡æ¯
*/
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
/**
* 仿¤å表ä¸å 餿å®éåä¸å
å«çææå
ç´ ã
*/
public boolean removeAll(Collection> c) {
Objects.requireNonNull(c);
//妿æ¤å表被修æ¹åè¿åtrue
return batchRemove(c, false);
}
/**
* ä»
ä¿çæ¤å表ä¸å
å«å¨æå®éåä¸çå
ç´ ã
*æ¢å¥è¯è¯´ï¼ä»æ¤å表ä¸å é¤å
¶ä¸ä¸å
å«å¨æå®éåä¸çææå
ç´ ã
*/
public boolean retainAll(Collection> c) {
Objects.requireNonNull(c);
return batchRemove(c, true);
}
/**
* ä»å表ä¸çæå®ä½ç½®å¼å§ï¼è¿åå表ä¸çå
ç´ ï¼ææ£ç¡®é¡ºåºï¼çå表è¿ä»£å¨ã
*æå®çç´¢å¼è¡¨ç¤ºåå§è°ç¨å°è¿åç第ä¸ä¸ªå
ç´ ä¸ºnext ã åå§è°ç¨previouså°è¿åæå®ç´¢å¼å1çå
ç´ ã
*è¿åçå表è¿ä»£å¨æ¯fail-fast ã
*/
public ListIterator listIterator(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: "+index);
return new ListItr(index);
}
/**
*è¿åå表ä¸çå表è¿ä»£å¨ï¼æéå½ç顺åºï¼ã
*è¿åçå表è¿ä»£å¨æ¯fail-fast ã
*/
public ListIterator listIterator() {
return new ListItr(0);
}
/**
*以æ£ç¡®ç顺åºè¿å该å表ä¸çå
ç´ çè¿ä»£å¨ã
*è¿åçè¿ä»£å¨æ¯fail-fast ã
*/
public Iterator iterator() {
return new Itr();
}
```
### ArrayListæºç åæ
#### System.arraycopy()åArrays.copyOf()æ¹æ³
ããéè¿ä¸é¢æºç æä»¬åç°è¿ä¸¤ä¸ªå®ç°æ°ç»å¤å¶çæ¹æ³è¢«å¹¿æ³ä½¿ç¨èä¸å¾å¤å°æ¹é½ç¹å«å·§å¦ãæ¯å¦ä¸é¢add(int index, E element)æ¹æ³å°±å¾å·§å¦çç¨å°äºarraycopy()æ¹æ³è®©æ°ç»èªå·±å¤å¶èªå·±å®ç°è®©indexå¼å§ä¹åçæææååç§»ä¸ä¸ªä½ç½®:
```java
/**
* 卿¤å表ä¸çæå®ä½ç½®æå
¥æå®çå
ç´ ã
*å
è°ç¨ rangeCheckForAdd 对indexè¿è¡ç鿣æ¥ï¼ç¶åè°ç¨ ensureCapacityInternal æ¹æ³ä¿è¯capacityè¶³å¤å¤§ï¼
*åå°ä»indexå¼å§ä¹åçæææååç§»ä¸ä¸ªä½ç½®ï¼å°elementæå
¥indexä½ç½®ï¼æåsizeå 1ã
*/
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
//arraycopy()æ¹æ³å®ç°æ°ç»èªå·±å¤å¶èªå·±
//elementData:æºæ°ç»;index:æºæ°ç»ä¸çèµ·å§ä½ç½®;elementDataï¼ç®æ æ°ç»ï¼index + 1ï¼ç®æ æ°ç»ä¸çèµ·å§ä½ç½®ï¼ size - indexï¼è¦å¤å¶çæ°ç»å
ç´ çæ°éï¼
System.arraycopy(elementData, index, elementData, index + 1, size - index);
elementData[index] = element;
size++;
}
```
åå¦toArray()æ¹æ³ä¸ç¨å°äºcopyOf()æ¹æ³
```java
/**
*以æ£ç¡®ç顺åºï¼ä»ç¬¬ä¸ä¸ªå°æåä¸ä¸ªå
ç´ ï¼è¿åä¸ä¸ªå
嫿¤åè¡¨ä¸ææå
ç´ çæ°ç»ã
*è¿åçæ°ç»å°æ¯âå®å
¨çâï¼å 为该å表ä¸ä¿ç对å®çå¼ç¨ã ï¼æ¢å¥è¯è¯´ï¼è¿ä¸ªæ¹æ³å¿
é¡»åé
ä¸ä¸ªæ°çæ°ç»ï¼ã
*å æ¤ï¼è°ç¨è
å¯ä»¥èªç±å°ä¿®æ¹è¿åçæ°ç»ã æ¤æ¹æ³å
å½åºäºéµåååºäºéåçAPIä¹é´çæ¡¥æ¢ã
*/
public Object[] toArray() {
//elementDataï¼è¦å¤å¶çæ°ç»ï¼sizeï¼è¦å¤å¶çé¿åº¦
return Arrays.copyOf(elementData, size);
}
```
##### 两è
èç³»ä¸åºå«
**èç³»ï¼**
ç两è
æºä»£ç å¯ä»¥åç°`copyOf()`å
é¨è°ç¨äº`System.arraycopy()`æ¹æ³
**åºå«ï¼**
1. arraycopy()éè¦ç®æ æ°ç»ï¼å°åæ°ç»æ·è´å°ä½ èªå·±å®ä¹çæ°ç»éï¼èä¸å¯ä»¥éæ©æ·è´çèµ·ç¹åé¿åº¦ä»¥åæ¾å
¥æ°æ°ç»ä¸çä½ç½®
2. copyOf()æ¯ç³»ç»èªå¨å¨å
鍿°å»ºä¸ä¸ªæ°ç»ï¼å¹¶è¿å该æ°ç»ã
#### ArrayList æ ¸å¿æ©å®¹ææ¯
```java
//ä¸é¢æ¯ArrayListçæ©å®¹æºå¶
//ArrayListçæ©å®¹æºå¶æé«äºæ§è½ï¼å¦ææ¯æ¬¡åªæ©å
ä¸ä¸ªï¼
//é£ä¹é¢ç¹çæå
¥ä¼å¯¼è´é¢ç¹çæ·è´ï¼é使§è½ï¼èArrayListçæ©å®¹æºå¶é¿å
äºè¿ç§æ
åµã
/**
* 妿å¿
è¦ï¼å¢å æ¤ArrayListå®ä¾ç容éï¼ä»¥ç¡®ä¿å®è³å°è½å®¹çº³å
ç´ çæ°é
* @param minCapacity æéçæå°å®¹é
*/
public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
// any size if not default element table
? 0
// larger than default for default empty table. It's already
// supposed to be at default size.
: DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
//å¾å°æå°æ©å®¹é
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
// è·åé»è®¤ç容éåä¼ å
¥åæ°çè¾å¤§å¼
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
//夿æ¯å¦éè¦æ©å®¹,ä¸é¢ä¸¤ä¸ªæ¹æ³é½è¦è°ç¨
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// å¦æè¯´minCapacityä¹å°±æ¯æéçæå°å®¹é大äºä¿åArrayListæ°æ®çæ°ç»çé¿åº¦çè¯ï¼å°±éè¦è°ç¨grow(minCapacity)æ¹æ³æ©å®¹ã
//è¿ä¸ªminCapacityå°åºä¸ºå¤å°å¢ï¼ä¸¾ä¸ªä¾å卿·»å å
ç´ (add)æ¹æ³ä¸è¿ä¸ªminCapacityç大å°å°±ä¸ºç°å¨æ°ç»çé¿åº¦å 1
if (minCapacity - elementData.length > 0)
//è°ç¨growæ¹æ³è¿è¡æ©å®¹ï¼è°ç¨æ¤æ¹æ³ä»£è¡¨å·²ç»å¼å§æ©å®¹äº
grow(minCapacity);
}
```
```java
/**
* ArrayListæ©å®¹çæ ¸å¿æ¹æ³ã
*/
private void grow(int minCapacity) {
//elementData为ä¿åArrayListæ°æ®çæ°ç»
///elementData.lengthæ±æ°ç»é¿åº¦elementData.sizeæ¯æ±æ°ç»ä¸çå
ç´ ä¸ªæ°
// oldCapacity为æ§å®¹éï¼newCapacity为æ°å®¹é
int oldCapacity = elementData.length;
//å°oldCapacity å³ç§»ä¸ä½ï¼å
¶ææç¸å½äºoldCapacity /2ï¼
//æä»¬ç¥éä½è¿ç®çé度è¿è¿å¿«äºæ´é¤è¿ç®ï¼æ´å¥è¿ç®å¼çç»æå°±æ¯å°æ°å®¹éæ´æ°ä¸ºæ§å®¹éç1.5åï¼
int newCapacity = oldCapacity + (oldCapacity >> 1);
//ç¶åæ£æ¥æ°å®¹éæ¯å¦å¤§äºæå°éè¦å®¹éï¼è¥è¿æ¯å°äºæå°éè¦å®¹éï¼é£ä¹å°±ææå°éè¦å®¹éå½ä½æ°ç»çæ°å®¹éï¼
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//åæ£æ¥æ°å®¹éæ¯å¦è¶
åºäºArrayListæå®ä¹çæå¤§å®¹éï¼
//è¥è¶
åºäºï¼åè°ç¨hugeCapacity()æ¥æ¯è¾minCapacityå MAX_ARRAY_SIZEï¼
//妿minCapacity大äºMAX_ARRAY_SIZEï¼åæ°å®¹éå为Interger.MAX_VALUEï¼å¦åï¼æ°å®¹é大å°å为 MAX_ARRAY_SIZEã
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);
}
```
ããæ©å®¹æºå¶ä»£ç å·²ç»åäºè¯¦ç»çè§£éãå¦å¤å¼å¾æ³¨æçæ¯å¤§å®¶å¾å®¹æå¿½ç¥çä¸ä¸ªè¿ç®ç¬¦ï¼**ç§»ä½è¿ç®ç¬¦**
ãã**ç®ä»**ï¼ç§»ä½è¿ç®ç¬¦å°±æ¯å¨äºè¿å¶çåºç¡ä¸å¯¹æ°åè¿è¡å¹³ç§»ãæç
§å¹³ç§»çæ¹ååå¡«å
æ°åçè§åå为ä¸ç§:<<(左移)ã>>(带符å·å³ç§»)å>>>(æ 符å·å³ç§»)ã
ãã**ä½ç¨**ï¼**对äºå¤§æ°æ®ç2è¿å¶è¿ç®,ä½ç§»è¿ç®ç¬¦æ¯é£äºæ®éè¿ç®ç¬¦çè¿ç®è¦å¿«å¾å¤,å 为ç¨åºä»
ä»
ç§»å¨ä¸ä¸èå·²,ä¸å»è®¡ç®,è¿æ ·æé«äºæç,èçäºèµæº**
ããæ¯å¦è¿éï¼int newCapacity = oldCapacity + (oldCapacity >> 1);
å³ç§»ä¸ä½ç¸å½äºé¤2ï¼å³ç§»nä½ç¸å½äºé¤ä»¥ 2 ç n 次æ¹ãè¿é oldCapacity ææ¾å³ç§»äº1使以ç¸å½äºoldCapacity /2ã
**å¦å¤éè¦æ³¨æçæ¯ï¼**
1. java ä¸ç**length 屿§**æ¯é对æ°ç»è¯´ç,æ¯å¦è¯´ä½ 声æäºä¸ä¸ªæ°ç»,æ³ç¥éè¿ä¸ªæ°ç»çé¿åº¦åç¨å°äº length è¿ä¸ªå±æ§.
2. java ä¸ç**length()æ¹æ³**æ¯é对å 符串String说ç,妿æ³çè¿ä¸ªå符串çé¿åº¦åç¨å° length()è¿ä¸ªæ¹æ³.
3. .java ä¸ç**size()æ¹æ³**æ¯é对æ³åéå说ç,妿æ³çè¿ä¸ªæ³åæå¤å°ä¸ªå
ç´ ,å°±è°ç¨æ¤æ¹æ³æ¥æ¥ç!
#### å
é¨ç±»
```java
(1)private class Itr implements Iterator
(2)private class ListItr extends Itr implements ListIterator
(3)private class SubList extends AbstractList implements RandomAccess
(4)static final class ArrayListSpliterator implements Spliterator
```
ããArrayListæå个å
é¨ç±»ï¼å
¶ä¸ç**Itræ¯å®ç°äºIteratoræ¥å£**ï¼åæ¶éåäºéé¢ç**hasNext()**ï¼ **next()**ï¼ **remove()** çæ¹æ³ï¼å
¶ä¸ç**ListItr** ç»§æ¿ **Itr**ï¼å®ç°äº**ListIteratoræ¥å£**ï¼åæ¶éåäº**hasPrevious()**ï¼ **nextIndex()**ï¼ **previousIndex()**ï¼ **previous()**ï¼ **set(E e)**ï¼ **add(E e)** çæ¹æ³ï¼æä»¥è¿ä¹å¯ä»¥çåºäº **IteratoråListIteratorçåºå«:** ListIteratorå¨Iteratorçåºç¡ä¸å¢å äºæ·»å 对象ï¼ä¿®æ¹å¯¹è±¡ï¼éåéåçæ¹æ³ï¼è¿äºæ¯Iteratorä¸è½å®ç°çã
### ArrayListç»å
¸Demo
```java
package list;
import java.util.ArrayList;
import java.util.Iterator;
public class ArrayListDemo {
public static void main(String[] srgs){
ArrayList arrayList = new ArrayList();
System.out.printf("Before add:arrayList.size() = %d\n",arrayList.size());
arrayList.add(1);
arrayList.add(3);
arrayList.add(5);
arrayList.add(7);
arrayList.add(9);
System.out.printf("After add:arrayList.size() = %d\n",arrayList.size());
System.out.println("Printing elements of arrayList");
// ä¸ç§é忹弿å°å
ç´
// 第ä¸ç§ï¼éè¿è¿ä»£å¨éå
System.out.print("éè¿è¿ä»£å¨éå:");
Iterator it = arrayList.iterator();
while(it.hasNext()){
System.out.print(it.next() + " ");
}
System.out.println();
// 第äºç§ï¼éè¿ç´¢å¼å¼éå
System.out.print("éè¿ç´¢å¼å¼éå:");
for(int i = 0; i < arrayList.size(); i++){
System.out.print(arrayList.get(i) + " ");
}
System.out.println();
// 第ä¸ç§ï¼for循ç¯éå
System.out.print("for循ç¯éå:");
for(Integer number : arrayList){
System.out.print(number + " ");
}
// toArrayç¨æ³
// 第ä¸ç§æ¹å¼(æå¸¸ç¨)
Integer[] integer = arrayList.toArray(new Integer[0]);
// 第äºç§æ¹å¼(容æçè§£)
Integer[] integer1 = new Integer[arrayList.size()];
arrayList.toArray(integer1);
// æåºå¼å¸¸ï¼java䏿¯æåä¸è½¬å
//Integer[] integer2 = new Integer[arrayList.size()];
//integer2 = arrayList.toArray();
System.out.println();
// 卿å®ä½ç½®æ·»å å
ç´
arrayList.add(2,2);
// å 餿å®ä½ç½®ä¸çå
ç´
arrayList.remove(2);
// å 餿å®å
ç´
arrayList.remove((Object)3);
// 夿arrayListæ¯å¦å
å«5
System.out.println("ArrayList contains 5 is: " + arrayList.contains(5));
// æ¸
空ArrayList
arrayList.clear();
// 夿ArrayListæ¯å¦ä¸ºç©º
System.out.println("ArrayList is empty: " + arrayList.isEmpty());
}
}
```