参考链接
【原创】这道Java基础题真的有坑!我求求你,认真思考后再回答。
https://www.cnblogs.com/thisiswhy/p/12067093.html
【原创】这道Java基础题真的有坑!我也没想到还有续集。
https://www.cnblogs.com/thisiswhy/p/12072467.html
问题引入
小马哥出的题
网友回答:
- 什么也不会发生,remove之后,list中的数据会被清空。
- remove的方法调用错误,入参应该是index(数组下标)。
- 并发操作的时候会出现异常。
- 会发生ConcurrentModifyException。
阿里Java开发规范
这里带来一个固定的知识点:不要在foreach中进行元素的remove/add操作,会触发ConcurrentModifyException。
即使使用Iterator,在多线程的场景下,也要对Iterator进行加锁处理。跑一跑代码
正例
@Test
public void testRightForeach() {
List<String> list = new ArrayList<>();
list.add("公众号");
list.add("why技术");
System.out.println("remove前的list = " + list);
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if ("公众号".equals(item)) {
iterator.remove();
}
}
System.out.println("remove后的list = " + list);
}
小彩蛋
在JDK1.8中,官方实现了上面的模板代码,提供了一个便利方法:Collection.removeIf()
反例
出乎意料的反例
上面这段代码的执行结果是什么?抛出ConcurrentModifyException吗?错了!结果是正常执行!@Test
public void testAmazingWrongForeach() {
List<String> list = new ArrayList<>();
list.add("公众号");
list.add("why技术");
System.out.println("remove前的list = " + list);
for (String item : list) {
if ("公众号".equals(item)) {
list.remove(item);
}
}
System.out.println("remove后的list = " + list);
}
意料之中的反例