对List集合进行遍历的时候,有几种方式:for,forEach,Iterator;在需要remove的时候,会有一些坑在里面,记录一下。
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("b");
list.add("c");
for (int i = 0; i < list.size(); i++){
if ("b".equals(list.get(i))){
list.remove(i);
}
}
System.out.println(list);
这时候打印就会出现:a,b,c;
也就是说无法删除2个相邻的同样数据。
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index); //存放索引处的值
int numMoved = size - index - 1; //记录要移动的元素有几个,移动几步
if (numMoved > 0) //index 后的数据向前移
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
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));
}
ArrayList源码里面关于有2个移除数据的方法,一个是 下标,一个是 对象。
主要就是根据下表删除数据时,删除第一个"b"时,索引是 “1”,之后的"b"向前移,检测下标"2"时。发现数据是"c",不会删除。
所以可以下标同步修改来实现。也就是list(i- -),或者修改控制循环进行同步for(int i=list.size()-1;i>=0;i- -)
推荐使用迭代器Iterator,安全。
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("b");
Iterator<String> it = list.iterator();
while (it.hasNext()){
if ("b".equals(it.next())){
it.remove();
}
}
System.out.println(list);
注意:不要再forEach和Iterator中使用remove(i)。