参考链接

【原创】这道Java基础题真的有坑!我求求你,认真思考后再回答。
https://www.cnblogs.com/thisiswhy/p/12067093.html
【原创】这道Java基础题真的有坑!我也没想到还有续集。
https://www.cnblogs.com/thisiswhy/p/12072467.html

问题引入

小马哥出的题

ArrayList的Iterator问题(来自Why技术) - 图1
网友回答:

  1. 什么也不会发生,remove之后,list中的数据会被清空。
  2. remove的方法调用错误,入参应该是index(数组下标)。
  3. 并发操作的时候会出现异常。
  4. 会发生ConcurrentModifyException。

    阿里Java开发规范

    ArrayList的Iterator问题(来自Why技术) - 图2
    这里带来一个固定的知识点:不要在foreach中进行元素的remove/add操作,会触发ConcurrentModifyException。
    即使使用Iterator,在多线程的场景下,也要对Iterator进行加锁处理。

    跑一跑代码

    正例

    1. @Test
    2. public void testRightForeach() {
    3. List<String> list = new ArrayList<>();
    4. list.add("公众号");
    5. list.add("why技术");
    6. System.out.println("remove前的list = " + list);
    7. Iterator<String> iterator = list.iterator();
    8. while (iterator.hasNext()) {
    9. String item = iterator.next();
    10. if ("公众号".equals(item)) {
    11. iterator.remove();
    12. }
    13. }
    14. System.out.println("remove后的list = " + list);
    15. }

    小彩蛋

    在JDK1.8中,官方实现了上面的模板代码,提供了一个便利方法: Collection.removeIf()

    反例

    出乎意料的反例

    1. @Test
    2. public void testAmazingWrongForeach() {
    3. List<String> list = new ArrayList<>();
    4. list.add("公众号");
    5. list.add("why技术");
    6. System.out.println("remove前的list = " + list);
    7. for (String item : list) {
    8. if ("公众号".equals(item)) {
    9. list.remove(item);
    10. }
    11. }
    12. System.out.println("remove后的list = " + list);
    13. }
    上面这段代码的执行结果是什么?抛出ConcurrentModifyException吗?错了!结果是正常执行!

    意料之中的反例