Collection是最基本的集合接口
接口中定义的所有方法:
public boolean add(E object);
public boolean addAll(Collection<? extends E> collection);
public void clear();
public boolean contains(Object object);
public boolean containsAll(Collection<?> collection);
public boolean equals(Object object);
public int hashCode();
public boolean isEmpty();
public Iterator<E>iterator();
public boolean remove(Object object);
public boolean removeAll(Collection<?> collection);
public boolean retainAll(Collection<?> collection);
public int size();
public Object[] toArray();
public <T> T[] toArray(T[] array);
继承关系
ArrayList:重要的成员变量以及构造方法
public class ArrayList<E> extends AbstractList<E> implements Cloneable, Serializable, RandomAccess{
//Google工程师关于一个容量调优参数(关系到扩容)
private static final int MIN_CAPACITY_INCREMENT = 12;
//反序列化的数组集合,也是我们arrayList使用的底层实现
transient Object[] array;
//集合元素数量
int size;
//我们常用的构造方法,默认就是一个Empty集合
public ArrayList() {
//一个长度为0的数组
array = EmptyArray.OBJECT;
}
}
- 增加
@Override public boolean add(E object) {
//使用局部变量操作集合,处于安全性考虑,不在array变量上进行操作
Object[] a = array;
int s = size;
//该if条件说明,元素数量和数组长度相等,这表示需要对于数组进行扩容
if (s == a.length) {
//扩容采用三目运算符进行,这里就使用掉了前文说过的容量调优参数MIN_CAPACITY_INCREMENT
Object[] newArray = new Object[s +
(s < (MIN_CAPACITY_INCREMENT / 2) ?
MIN_CAPACITY_INCREMENT : s >> 1)];
//native的copy方法复制一个新的数组
System.arraycopy(a, 0, newArray, 0, s);
array = a = newArray;
}
//将数据添加到数组中
a[s] = object;
//集合元素数量+1
size = s + 1;
//计数器+1
modCount++;
return true;
}
@Override
public void add(int index, E object) {
Object[] a = array;
int s = size;
if (index > s || index < 0) {
throwIndexOutOfBoundsException(index, s);
}
if (s < a.length) {
System.arraycopy(a, index, a, index + 1, s - index);
} else {
// assert s == a.length;
Object[] newArray = new Object[newCapacity(s)];
System.arraycopy(a, 0, newArray, 0, index);
System.arraycopy(a, index, newArray, index + 1, s - index);
array = a = newArray;
}
a[index] = object;
size = s + 1;
modCount++;
}
上面这两幅图我们通过构造和add方法相信都能很好的理解
- 删除
@Override public E remove(int index) {
Object[] a = array;
int s = size;
//如果index超出元素数量抛出异常
if (index >= s) {
throwIndexOutOfBoundsException(index, s);
}
@SuppressWarnings("unchecked") E result = (E) a[index];
System.arraycopy(a, index + 1, a, index, --s - index);
a[s] = null; // Prevent memory leak直接将对象置空
//将--后的s赋值给size,变更数组长度
size = s;
//计数器++
modCount++;
return result;
}
- 修改
@Override public E set(int index, E object) {
Object[] a = array;
if (index >= size) {
throwIndexOutOfBoundsException(index, size);
}
@SuppressWarnings("unchecked") E result = (E) a[index];
//直接替换成传入的object就好了
a[index] = object;
return result;
}
- 查找
@SuppressWarnings("unchecked") @Override public E get(int index) {
if (index >= size) {
throwIndexOutOfBoundsException(index, size);
}
//这个就比较简单了,就是直接根据index返回元素
return (E) array[index];
}
小贴士:想必大家都听说过,ArrayList插入删除慢,查找访问快,同过源码我们发现在使用add(int index, E object);函数插入的时候需要调用native的arrayCopy方法来创建新的数组,所以效率自然就低了,而访问的时候直接获取对象就可以。这也就是原因所在。