一、删除方法:
1)E remove(int index); 删除指定下标的元素,返回被删除元素内容
2) remove(Object obj); 删除指定元素
3) removeAll(Collection<?> c);删除两个集合的交集
4) retainAll(Collectino<?> c);保留两个集合的交集
5)clear(); 清空整个集合
二、改
E set(int index, E e); 使用符合类型的元素,替换指定下标元素,返回值是被替换的元素。
public E set(int index, E element) {
//检查索引是否合法
rangeCheck(index);
//旧值
E oldValue = elementData(index);
//赋新值
elementData[index] = element;
//返回旧值
return oldValue
}
三、查
1)int size(); 当前集合有效元素个数
2)boolean isEmpty(); 判断集合是否为空
3)boolean contains(Object obj); 判断指定元素是否存在
4)boolean containsAll(Collection<?> c); 判断指定集合是否为当前集合的子集合
5)Object[] toArray(); 获取当前集合中所有的Object类型数组
6)int indexOf(Oject obj); 获取指定元素在集合中第一次出现的的下标位置
7)int lastIndexOf(Object obj); 获取最后一次出现的下标位置
8)E get(int index); 获取集合中指定下标对应的元素
9)List subList(int fromIndex, int endIndex);
- indexOf()方法:查找数组里面是否存在指定元素
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;
}
- toArray();返回一个包含此集合中所有元素的数组。
public Object[] toArray() {
//将集合赋值为数组
return Arrays.copyOf(elemtentData, size);
}
- boolean contains(Object obj); 判断指定元素是否存在
public boolean contains(Object o) {
// 通过调用 indexOf 方法返回的下标来判断是否存在该元素
return indexOf(o) >= 0;
}
//返回指定元素在集合中首次出现的索引,如果集合不包含该元素,则返回-1
public int indexOf(Object o) {
// 如果指定元素为 null
if (o == null) {
// 从头遍历所有元素,null 用 == 判断,返回第一次 null 出现的下标
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
// 从头遍历所有元素,使用 equals 判断,返回第一次该元素出现的下标
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
// 不存在该元素则返回 -1
return -1;
}
- List subList(int fromIndex, int endIndex);
/**
* 返回集合中指定 [fromIndex, toIndex) 位置元素构成的集合
* 如果 fromIndex == toIndex,返回空集合
*/
public List<E> subList(int fromIndex, int toIndex) {
// 检测子集的下标是否越界
subListRangeCheck(fromIndex, toIndex, size);
// 通过构造 SubList 返回,SubList 和 ArrayList 引用是同一个对象
return new SubList(this, 0, fromIndex, toIndex);
}
/*
* 检测子集的下标是否越界
*/
static void subListRangeCheck(int fromIndex, int toIndex, int size) {
// 检测 fromIndex 是否小于 0
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
// 检测 toIndex 是否大于 size
if (toIndex > size)
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
// 检测 fromIndex 是否大于 toIndex
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex + ")");
}
四、注意:
1、ArrayList可以存放null;
2、ArrayList本质是一个elementData数组
3、arrayList区别于数组的地方在于能够自动扩展大小,其中关键的方法就是gorw()方法,不支持缩容。
4、arrayList由于本质是数组,所以它在数据的查询方面会很快,而在插入删除这些方面,性能下降很多,有移动很多数据才能达到应有的效果。
(1)ArrayList 本质上是一个可变数组,内部的元素可以直接通过get与set方法进行访问。元素顺序存储,随机访问很快,删除非头尾元素慢,新增元素慢而且费资源。
较适用于无频繁增删的情况,比数组效率低,如果不是需要可变数组,可考虑使用数组,非线程安全。
(2)LinkedList 是一个双链表,在添加和删除元素时具有比ArrayList更好的性能。但在get与set方面弱于ArrayList。
适用于 :没有大规模的随机读取,有大量的增加/删除操作.随机访问很慢,增删操作很快,不耗费多余资源,允许null元素,非线程安全。
(3)Vector (类似于ArrayList)线程安全的, Vector和ArrayList在更多元素添加进来时会请求更大的空间。Vector每次请求其大小的双倍空间,而ArrayList每次对size增长50%。
五、特征分析
一、增删慢:
- 增加慢:
- 有可能触发扩容操作。在扩容方法操作中,从原数组拷贝数据到新数组浪费时间,同时在扩容操作会出现无效内 存销毁问题,同样浪费时间。
- 插入数据到指定下标位置,从插入位置开始,数组中的其他数据会整体向后移动。移动操作浪费时间。
- 删除慢:
- 删除指定下标元素,数组中的元素整体向前移动。
- 删除元素较多情况下,会导致空间冗余。空间效率较低
二、查询快:
- 【寻址操作】
ArrayList底层数据操作方式为数组方式,数组+下标获取对应元素的操作效率是非常高!!!
是CPU根据对应【地址】直接访问操作。