java采坑总结
作者:互联网
一、一些特殊集合
1 、把 Array 转换 为 ArrayList
List<String> list = Arrays.asList(arr);
不能 用这样构造出的list 进行 添加 、删除 操作。
但实际上,Arrays.asList() 返回的 ArrayList 并不是 java.util.ArrayList,而是 Arrays 的内部私有类
java.util.Arrays.ArrayList。虽然名字完全相同,都是 ArrayList,但两个类有着很大的不同。
Arrays.ArrayList 虽然有set()、get() 和 contains()
等方法,但却没有一个方法用来添加元素,因此它的大小是固定的。
如果想创建一个真正的list 需要,在new 出来的 ArrayList 构造出来。
List<String> list = new ArrayList<String>(Arrays.asList(arr));
2、不要在foreach里面进行元素的remove/add操作,remove请使用Iterator方式
我们都知道增加for循环即foreach循环其实就是根据list对象创建一个iterator迭代对象,用这个迭代对象来遍历list,相当于list对象中元素的遍历托管给了iterator,如果要对list进行增删操作,都必须经过iterator。
每次foreach循环时都有以下两个操作
iterator.hasNext(); //判读是否有下个元素
item = iterator.next(); //下个元素是什么,并把它赋给item。
List<String> a = new ArrayList<>();
a.add("1");
a.add("2");
for (String temp : a) {
if("1".equals(temp)){
a.remove(temp);
}
}
上面代码在编译和运行时都不会报错,并且也能正常remove掉元素,但是如果将"1" 换成"2",运行时就会报ConcurrentModificationException.首选需要分析ArrayList的源码,ArrayList类继承自AbstractList类,该类中有一个成员变量:
protected transient int modCount = 0;
modCount用于记录变更次数,当add或者remove时,都会自增1
foreach时会调用ArrayList的iterator方法,该返回一个Itr类型的内部类,该内部类有几个需要注意的成员变量:
int cursor; // index of next element to return
int expectedModCount = modCount;
cursor用于记录获取到哪个元素,expectedModCount用于记录变更次数,如果在iter过程中删除了一个元素,在调用iter.next()时会调用 Itr.checkForComdification()方法校验是否有变更:
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
如果expectedModCount != modCount,就会报ConcurrentModificationException异常.
凌云追梦 发布了17 篇原创文章 · 获赞 1 · 访问量 605 私信 关注标签:总结,java,采坑,iterator,Arrays,ArrayList,list,remove,modCount 来源: https://blog.csdn.net/weixin_43975771/article/details/103949006