问题一:移除元素有漏掉
操作:
@SuppressWarnings({ "rawtypes", "unchecked" })
private static void listRemove() {
final ArrayList list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
System.out.println("list长度.size():" + list.size());
for (int i = 0; i < list.size(); i++) {
list.remove(i);
System.out.println("移除第" + i + "个元素之后list内元素有:" + list.toString()
+ "list长度.size()为:" + list.size());
}
System.out.println("移除结束list内元素有:" + list.toString());
}
结果:
排查:
list.remove()方法操作为:
public E remove(int index) {
RangeCheck(index);
modCount++;
E oldValue = (E) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
return oldValue;
}
方法System.arraycopy(elementData, index+1, elementData, index, numMoved);将移除位置后每一位向前复制一位第一次移动得到的elementData=[2,3,4,4,null.null,...]
方法 elementData[--size] = null; 将最后一位指向null方便GC回收
第一个元素移除结束后得到的list为[2,3,4],list元素位发生变化,第二次移除index=1移除元素为3得到的list为[2,4],size=2此时i=1,下次移除i=2不符合条件,操作结束。
解决方式:
指定删除的位置或使用迭代器:
@SuppressWarnings({ "rawtypes", "unchecked" })
private static void listRemoveItr() {
final ArrayList list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
Iterator iterator = list.iterator();
System.out.println("删除前集合的长度为:" + list.size() + ":" + list);
for (; iterator.hasNext() && !"".equals(iterator.next());) {
iterator.remove();
}
System.out.println("删除后集合的长度为:" + list.size() + ":" + list);
}
问题二:ConcurrentModificationException异常
以上方式写成如下,会报java.util.ConcurrentModificationException异常:
@SuppressWarnings({ "rawtypes", "unchecked" })
private static void listRemoveItr() {
final ArrayList list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
Iterator iterator = list.iterator();
System.out.println("删除前集合的长度为:" + list.size() + ":" + list);
for (; iterator.hasNext() && !"".equals(iterator.next());) {
// iterator.remove();
list.remove(Integer.valueOf(3));
}
System.out.println("删除后集合的长度为:" + list.size() + ":" + list);
}
原因及修改方式:
https://www.cnblogs.com/andy-zhou/p/5339683.html