普通for循环正序删除
public static void remove(List<T> list, T s) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals(s)) {
list.remove(list.get(i));
}
}
}
结论:删除过程中元素向左移动,不能删除重复的元素。
普通for循环倒序删除
public static void remove(List<T> list, T s) {
for (int i = list.size() - 1; i >= 0; i--) {
if (list.get(i).equals(s)) {
list.remove(list.get(i));
}
}
}
结论:删除过程中元素向左移动,可以删除重复的元素。
增强for循环删除
public static void remove(List<T> list, T s) {
for (T o : list) {
if (o.equals(s)) {
list.remove(o);
}
}
}
结论:使用ArrayList的remove()方法删除,产生并发修改异常ConcurrentModificationException
。
迭代器遍历,使用List集合的remove方法删除
public static void remove(List<T> list, T s) {
Iterator<T> iterator = list.iterator();
while (iterator.hasNext()) {
if (iterator.next().equals(s)) {
list.remove(iterator.next());
}
}
}
结论:使用ArrayList的remove()方法删除,产生并发修改异常ConcurrentModificationException
。
迭代器,使用迭代器的remove方法删除
public static void remove(List<T> list, T s) {
Iterator<T> iterator = list.iterator();
while (iterator.hasNext()) {
if (iterator.next().equals(s)) {
iterator.remove();
}
}
}
结论:使用迭代器的remove()方法删除,可以删除重复的元素,但不推荐使用。
源码分析
根据索引删除
public E remove(int index) {
// 检查索引是否越界
rangeCheck(index);
// 列表被修改(add和remove操作)次数+1
modCount++;
// 保存要删除的值
E oldValue = elementData(index);
// 计算移动的元素数量
int numMoved = size - index - 1;
if (numMoved > 0)
// 删除位置后面的元素向左移动,这里是用数组拷贝实现的
System.arraycopy(elementData, index+1, elementData, index, numMoved);
// 将最后一个位置引用设为null,使垃圾回收器回收这块内存
elementData[--size] = null; // clear to let GC do its work
// 返回删除元素的值
return oldValue;
}
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
根据元素删除
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) {
// 修改次数+1
modCount++;
// 计算移动的元素数量
int numMoved = size - index - 1;
if (numMoved > 0)
// 数组拷贝实现元素向左移动
System.arraycopy(elementData, index+1, elementData, index, numMoved);
// 将最后一个位置引用设为null
elementData[--size] = null; // clear to let GC do its work
}