Java集合框架——ArrayList
List介面下常用的實現類——ArrayList
1、特點
1)底層實現是陣列
2)資料可重複
3)可以有多個null
4)儲存的是單個值
5)保證插入的資料有序
6)查詢、修改效率高;刪除、增加效率低
2、常用實現方法
int size();//獲取儲存資料的個數
boolean isEmpty();//判斷集合是否為空
boolean contains(Object o);//判斷集合當中是否存在該元素
Iterator<E> iterator();//例項化迭代器物件(遍歷)
Object[] toArray();//將集合轉化為陣列
boolean add(E e);//往集合中新增元素
boolean remove(Object o);//從集合中刪除元素(刪除指定的元素)
boolean containsAll(Collection<?> c)//判斷集合中是否存在傳入集合的所有元素
void clear();//對集合所有元素刪除
3、ArrayList原始碼解讀
1)繼承關係
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
繼承AbstractList類,實現了List<E>介面,ArrayList是List介面的一個實現類
Cloneable 可以克隆、java.io.Serializable 可以進行序列化和反序列化操作
2)基本屬性
a.陣列的預設初始容量
private static final int DEFAULT_CAPACITY = 10;
因為ArrayList底層是由一個Object[]陣列構成,而這個Object[]陣列的預設長度是10,所以ArrayList長度預設容量是10。
b.陣列的初始化使用
private static final Object[] EMPTY_ELEMENTDATA = {};
c.ArrayList的底層資料結構是陣列
private transient Object[] elementData;
d.集合中儲存元素的個數
private int size;
e.modCount表示的是版本控制,新增,刪除,修改之類的操作都會++操作
protected transient int modCount = 0;
3)建構函式
a.//有參構造,引數表示陣列初始大小
直接對elementData屬性進行初始化
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
b.//無參構造,elementData陣列為空
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA;
}
c.//建構函式,引數是集合型別的一個物件
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();//將集合轉化為陣列
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
4)增長方式
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);//按原陣列的大小進行1.5倍擴容
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);
}
5)增刪改查操作
a.增加元素
public boolean add(E e) {//即相當於尾插
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
判斷陣列是否為空,若為空,陣列大小設定為10
如果需要擴容,陣列按照1.5倍大小進行擴容
將元素插入陣列elementData,並且size+1
特點:儲存重複資料,可以儲存null
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++;
}
b.刪除元素
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;
}
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;
}
要對值進行拆包操作(list.remove(Integer.valueOf(o));)才可以呼叫此remove方法
特點:
陣列起始元素是0
找到第一個出現的元素直接刪除並返回
時間複雜度o(n)
c.獲取當前元素
public E get(int index) {//通過索引位置直接查詢陣列elementData的元素
rangeCheck(index);
return elementData(index);
}
補充:兩個集合的交集、並集、差集
並集:兩集合所有元素的總和
交集:兩個集合中共有元素,即你有我也有的
差集:集合a中除了和集合b共有元素之外的元素,a與b的差集;即我有你沒有的
比如:集合A:1 2 3 集合B:3 4 5
則A與B的並集是1 2 3 3 4 5,交集:3,A與B的差集:1 2 ,B與A的差集:4 5
ArrayList<Integer> a=new ArrayList<>();
a.add(1);
a.add(2);
a.add(3);
ArrayList<Integer> b=new ArrayList<>();
b.add(3);
b.add(4);
b.add(5);
//兩個集合的並集
a.addAll(b);
//兩個集合的交集
a.retainAll(b);
//a與b的差集
b.retainAll(a);
a.removeAll(b);
ArrayList與陣列的異同點?
不同點:1)ArrayList只能儲存引用資料型別;而陣列既可以儲存基本資料型別也可以儲存引用資料型別;
2)ArrayList的大小可以動態指定,它的大小可在初始化時指定也可以不指定,也就是說該物件的空間可以任意增加; 而陣列在初始化時必須指定大小;
3)ArrayList不支援多維,而陣列支援多維。
相同點:底層是陣列,具有陣列的特性,擁有索引,可以快速找到元素