为什么迭代器可以remove掉集合的元素,改变集合容器的结构?
// 在使用迭代器遍历时,可使用迭代器的remove方法,因为Iterator的remove方法中 有如下的操作:
// expectedModCount = modCount;
// 所以避免了ConcurrentModificationException的异常。
一般用普通的for循环(能获取到索引index确定元素位置的for语句,需要index来确定遍历的当前位置);正序或者倒序遍历并且删除,注意每次删除元素后都是减小了容器的size(),那么index的值在正向遍历时候要注意是否会跳过元素。
因为按照obj元素去删除,需要做一次遍历匹配出元素的lowest的index再去删除,所以按照obj元素参数去remove效率,低于,按照index索引参数去remove。
boolean remove(Object o);
else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
/*
* 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 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 class
TestRemove {
public static void main(String[] args) {
List<Integer> list=new ArrayList<>();
list.add(11);
list.add(12);
list.add(8);
list.add(13);
list.add(14);
list.add(15);
list.add(16);
// TestRemoveEle(list);
// TestRemoveAsc(list);
// TestRemoveForLoop(list);
// 采用普通for循环,通过索引的方式删除元素,需要注意的是我这里采用的是倒序遍历,如果正序遍历的话要注意索引的变化
// int 是下标 ,list.size() 返回值是下标int类型的
// for (int i = 0; i < list.size(); i++) {
// Integer num = list.get(list.size() - 1 - i);
// if(num>10) {
// list.remove(list.size() - 1 - i);
// }
// }
// TestRemoveDesc(list);
System.out.println("again :---by iterator---");
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
Integer i = iterator.next();
if (i % 2 == 0) {
iterator.remove();
}
}
// 执行结果 [11,13,15] , 通过迭代器删除集合内元素
for(Integer i : list){
System.out.println("again :"+i);
}
}
private static void TestRemoveDesc(List<Integer> list) {
// 倒序遍历,并删除元素,通过索引下标删除
int len= list.size();
for (int i = 0; i< len; i++) {
if (list.get(len - 1 - i) % 2 == 0) {
list.remove(len - 1 - i); //执行删除指定元素的功能 ,i是index索引下标,
// 执行结果 [11,13,15] ,
// again :11
// again :13
// again :15
}
}
}
private static void TestRemoveForLoop(List<Integer> list) {
for (int i = 0; i< list.size(); i++) {
if (list.get(list.size() - 1 - i) % 2 == 0) {
System.out.println("list.size() is :"+ list.size());
list.remove(list.size() - 1 - i); //执行删除指定元素的功能 ,i是index索引下标,
// 执行结果 [11,12,13,15] ,说明12 没有实现remove,说明下标不准确 ,因为list.size() 被每次重复计算
// list.size() is :7
// list.size() is :6
// list.size() is :5
// again :11
// again :12
// again :13
// again :15
}
}
}
private static void TestRemoveAsc(List<Integer> list) {
for (int i = 0; i< list.size(); i++) {
if (list.get(i) % 2 == 0) {
list.remove(i); //执行删除指定元素的功能 ,i是index索引下标,
// 执行结果 [11,8,13,15] ,说明8 没有实现remove,说明下标不准确
}
}
}
// Integer 是元素对象
private static void TestRemoveEle(List<Integer> list) {
for (Integer i = 0; i< list.size(); i++) {
if (list.get(i) % 2 == 0) {
list.remove(i); //执行删除指定位置的元素的功能 执行结果 [11,12,13,14,15,16] ,因为没有1,2,3这些元素,所以没有删除
}
}
}
}