您的位置:首页 > 其它

读阿里巴巴开发规范关于list集合操作的问题

2017-05-26 22:44 357 查看
工作清闲时候在读阿里java开发规范突然发现一个关于list集合操作有意思的点,觉的很有意思

我们都知道操作list数据集合时,如果使用迭代器并用list集合本身的remove方法移除数据时,会发生 java.util.ConcurrentModificationException 异常,

例:public class TestMain {

public static void main(String[] args) {
List<String> lists = new ArrayList<>();
lists.add("a");
lists.add("b");
lists.add("c");
Iterator<String> str = lists.iterator();
while (str.hasNext()) {
String s=  str.next();
lists.remove(s);
}

}
}
结果:Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:886)
at java.util.ArrayList$Itr.next(ArrayList.java:836)
at TestMain.main(TestMain.java:17)
这点只要仔细读一下ArrayList源码的人都会知道原因的
private class Itr implements Iterator<E> {
int cursor;
int lastRet = -1;
int expectedModCount = modCount;
主要就是ArrayList内部类中的
int expectedModCount = modCount;这个变量,
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;
}
这里面只修改了
modCount++;
导致
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
方法中的checkForComodification方法校验时不通过
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
但是开发规范中发举了一个反例
例:public class TestMain {

public static void main(String[] args) {
List<String> lists = new ArrayList<>();
lists.add("a");
lists.add("b");
//lists.add("c");//这行注释掉
Iterator<String> str = lists.iterator();
while (str.hasNext()) {
String s=  str.next();
lists.remove(s);
}

}
}
当list集合中只有两个元素时,确没有报异常,这里就会有点疑问了,仔细查看了源代码,原来问题出在这里,当第一次进入while循环,执行str.hastNext(),
之后,cursor=1,list.remove(s)一个元素后 size=1;
public boolean hasNext() {
return cursor != size;
}
由这个方法判断条件
cursor!=size,(其实集合里面还是有元素的哈),条件不满足就不会执行while循环里面的语句了。。所以就理所当然不会报
java.util.ConcurrentModificationException,真是醉了。。。。。。

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐