返回顶部
首页 > 资讯 > 精选 >Java中ArrayList陷阱实例分析
  • 826
分享到

Java中ArrayList陷阱实例分析

2023-06-29 07:06:44 826人浏览 独家记忆
摘要

这篇文章主要介绍“Java中ArrayList陷阱实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java中ArrayList陷阱实例分析”文章能帮助大家解决问题。问题分析疑惑满满小枫听到这个

这篇文章主要介绍“Java中ArrayList陷阱实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java中ArrayList陷阱实例分析”文章能帮助大家解决问题。

    问题分析

    疑惑满满

    小枫听到这个面试题的时候,心想这是什么水面试官,怎么问这么简单的题目,心想一个for循环加上equal判断再删除不就完事了吗?但是转念一想,不对,这里面肯定有陷阱,不然不会问这么看似简单的问题。小枫突然想起来之前写代码的时候好像遇到过这个问题,也是在ArrayList中删除指定元素,但是直接for循环remove元素的时候还抛出了异常,面试官的陷阱估计在这里。小枫暗自窃喜,找到了面试官埋下的陷阱。 小枫回想起当天的的测试情况,代码进行了脱敏改造。当初是要在ArrayList中删除指定元素,小枫三下五除二,酣畅淋漓的写下了如下的代码,信心满满的点了Run代码的按钮,结果尴尬了,抛异常了。

    public class TestListMain {    public static void main(String[] args) {        List<String> result = new ArrayList<>();        result.add("a");        result.add("b");        result.add("c");        result.add("d");        for (String s : result) {            if ("b".equals(s)) {                result.remove("b");            }        }    }}

    一个大大红色的异常马上就出来了,OMG,怎么会这样呢,感觉代码没什么问题啊,赶紧看看抛了什么异常,在哪里抛的异常吧。可以看出来抛了一个ConcurrentModificationException的异常,而且是在Itr这个类中的一个检测方法中抛出来的异常,这是怎么回事呢?我们的原始代码中并没有这个Itr代码,真是百思不得其解。

    Java中ArrayList陷阱实例分析

    拨云见日

    既然从源代码分析不出来,我们就看下源代码编译后的class文件中的内容是怎样的吧,毕竟class文件才是JVM真正执行的代码,不看不知道,一看吓一跳,jdk原来是这么玩的。原来如此,我们原始代码中的for-each语句,编译后的实际是以迭代器来代替执行的。

    public class TestListMain {    public TestListMain() {    }    public static void main(String[] args) {        List<String> result = new ArrayList();        result.add("a");        result.add("b");        result.add("c");        result.add("d");        //创建迭代器        Iterator var2 = result.iterator();        while(var2.hasNext()) {            String s = (String)var2.next();            if ("b".equals(s)) {                result.remove("b");            }        }    }}

    通过ArrayList创建的Itr这个内部类迭代器,于是for-each循环就转化成了迭代器加while循环的方式,原来看上去的for-each循环被挂羊头卖狗肉了。

      public Iterator<E> iterator() {        return new Itr();    }

    Itr这个内部类迭代器,通过判断hasNext()来判断迭代器是否有内容,而next()方法则获取迭代器中的内容。

     private class Itr implements Iterator<E> {        int cursor;       // index of next element to return        int lastRet = -1; // index of last element returned; -1 if no such        int expectedModCount = modCount;        Itr() {}        public boolean hasNext() {            return cursor != size;        }        @SuppressWarnings("unchecked")        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];        }     ...      }

    大致的过程如下所示:

    Java中ArrayList陷阱实例分析

    真正抛异常的地方是这个检测方法, 当modCount与expectedModCount不相等的时候直接抛出异常了。那我们要看下modCount以及expectedModCount分别是什么。这里的modCount代表ArrayList的修改次数,而expectedModCount代表的是迭代器的修改次数,在创建Itr迭代器的时候,将modCount赋值给了expectedModCount,因此在本例中一开始modCount和expectedModCount都是4(添加了四次String元素)。但是在获取到b元素之后,ArrayList进行了remove操作,因此modCount就累加为5了。因此在进行检查的时候就出现了不一致,最终导致了异常的产生。到此我们找到了抛异常的原因,循环使用迭代器进行循环,但是操作元素却是使用的ArrayList操作,因此迭代器在循环的时候发现元素被修改了所以抛出异常。

    Java中ArrayList陷阱实例分析

    我们再来思考下,为什么要有这个检测呢?这个异常到底起到什么作用呢?我们先来开下ConcurrentModificationException的注释是怎么描述的。简单理解就是不允许一个线程在修改集合,另一个线程在集合基础之上进行迭代。一旦检测到了这种情况就会通过fast-fail机制,抛出异常,防止后面的不可知状况。

    public class ConcurrentModificationException extends RuntimeException {    ...}

    如何正确的删除

    既然抛异常的原因是循环使用了迭代器,而删除使用ArrayList导致检测不通过。那么我们就循环使用迭代器,删除也是用迭代器,这样就可以保证一致了。

    public class TestListMain {    public static void main(String[] args) {        List<String> result = new ArrayList<>();        result.add("a");        result.add("b");        result.add("c");        result.add("d");       Iterator<String> iterator = list.iterator(); while (iterator .hasNext()) {String str = iterator.next();if ("b".equals(str)) {iterator.remove();}    }}

    关于“Java中ArrayList陷阱实例分析”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网精选频道,小编每天都会为大家更新不同的知识点。

    --结束END--

    本文标题: Java中ArrayList陷阱实例分析

    本文链接: https://lsjlt.com/news/323298.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • Java中ArrayList陷阱实例分析
      这篇文章主要介绍“Java中ArrayList陷阱实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java中ArrayList陷阱实例分析”文章能帮助大家解决问题。问题分析疑惑满满小枫听到这个...
      99+
      2023-06-29
    • ArrayList的陷阱实例分析
      这篇文章主要介绍“ArrayList的陷阱实例分析”,在日常操作中,相信很多人在ArrayList的陷阱实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”ArrayList的陷阱实例分析”的疑惑有所帮助!...
      99+
      2023-06-17
    • Java面试必备之ArrayList陷阱解析
      目录问题分析疑惑满满拨云见日回顾整个过程如何正确的删除总结问题分析 疑惑满满 小枫听到这个面试题的时候,心想这是什么水面试官,怎么问这么简单的题目,心想一个for循环加上equal判...
      99+
      2024-04-02
    • Python面试题陷阱实例分析
      这篇文章主要讲解了“Python面试题陷阱实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python面试题陷阱实例分析”吧!问题1:请问如何修改以下Python代码,使得下面的代码调...
      99+
      2023-06-17
    • Python陷阱与缺陷列表的示例分析
      Python陷阱与缺陷列表的示例分析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。我个人对陷阱的定义是这样的:代码看起来可以工作,但不是以你“想当然“”的方式。如果一段代码...
      99+
      2023-06-17
    • 分析java中藏在正则表达式里的陷阱
      这篇文章主要讲解了“分析java中藏在正则表达式里的陷阱”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“分析java中藏在正则表达式里的陷阱”吧!前几天线上一...
      99+
      2024-04-02
    • Java中常见的几个陷阱分别是什么
      这篇文章给大家介绍Java中常见的几个陷阱分别是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。java 中有很多,新手经常遇到的陷阱,下面主要包含自动装箱与拆箱不可变的String内存泄漏自增类型使用使用 “==”...
      99+
      2023-06-16
    • Lakehouse数据湖并发控制陷阱分析
      目录1. 概述2. 数据湖并发控制中的陷阱3. 模型 1:单写入,内联表服务4. 模型2:单写入,异步表服务5. 模型3:多写入1. 概述 如今数据湖上的事务被认为是 Lakehou...
      99+
      2024-04-02
    • 双重检查锁定模式Java中的陷阱案例
      目录1、简介2、Java中的双重检查锁定3、列举方案3.1 利用 ThreadLocal3.2 利用volatile(解决重排序问题)4、总结1、简介 双重检查锁定(也叫做双重检查锁...
      99+
      2024-04-02
    • Java中LinkedList和ArrayList的效率分析
      在 Java 中,LinkedList 和 ArrayList 的性能是不同的,具体取决于你所需要的操作。 对于频繁的插入和删除操作,LinkedList 的性能通常更好,因为它使用...
      99+
      2023-02-10
      Java LinkedList和ArrayList效率 Java LinkedList ArrayList
    • MySQL中ROUND函数进行四舍五入操作陷阱分析
      本文实例讲述了MySQL中ROUND函数进行四舍五入操作陷阱。分享给大家供大家参考,具体如下: 在MySQL中, ROUND 函数用于对查询结果进行四舍五入,不过最近使用ROUND函数四舍五入时意外发现并没...
      99+
      2024-04-02
    • python中randint函数的效率缺陷实例分析
      本篇内容介绍了“python中randint函数的效率缺陷实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、前言前几天,在写一个与差...
      99+
      2023-07-02
    • Node.js 中 OAuth 的陷阱和最佳实践
      常见的陷阱 不验证访问令牌:始终验证传入的访问令牌以确保其有效性和范围,以防止未授权访问。 不限制令牌权限:仔细管理访问令牌中授予的权限,以最小化数据泄露风险。 不刷新令牌:定期刷新令牌以确保访问不会中断,并防止黑客利用过期的令牌。 不...
      99+
      2024-02-19
      Node.js OAuth 2.0 最佳实践 身份验证
    • Spring事物基础知识及AOP相关陷阱分析
      目录一、事务的定义二、事务的属性三、Spring 事务的隔离级别3.1 隔离级别引出的问题3.1.1 脏读3.1.2 不可重复读3.1.3 幻读3.2 隔离级别四、Spring 事务...
      99+
      2024-04-02
    • Python 数据分析中的陷阱:避免常见错误的秘诀
      数据收集和准备 数据质量差:确保数据准确、完整且一致非常重要。对数据进行适当的清洗和变换以消除错误和异常值。 数据偏见:考虑数据的来源和收集方法。确保样本具有代表性,避免对结果产生偏见。 数据准备错误:将数据转换为不同的格式或结构时,要...
      99+
      2024-03-12
      数据分析的本质是将原始数据转化为有用的信息。Python 因其强大的数据处理库而成为数据分析的首选语言 但使用它时需要注意一些常见的陷阱。
    • ArrayList中自动扩充机制的示例分析
      这篇文章主要为大家展示了“ArrayList中自动扩充机制的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“ArrayList中自动扩充机制的示例分析”这篇文章吧。ArrayList li...
      99+
      2023-05-30
      java arraylist
    • java中object类实例分析
      问:什么是Object类?答:Object类存储在java.lang包中,是所有java类(Object类除外)的终极父类。当然,数组也继承了Object类。然而,接口是不继承Object类的,Object类不作为接口的父类。下面,我们就通...
      99+
      2023-05-30
      java object类 ava
    • Java中BigDecimal,DateFormatter 和迭代器的"陷阱"
      前言: 使用 IDEA 创建一个 Maven 项目 calculate-date-traps 并导入 Junit 依赖。 <dependency> <gro...
      99+
      2024-04-02
    • java中class实例的示例分析
      这篇文章将为大家详细讲解有关java中class实例的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1、结构说明(1)class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类(2...
      99+
      2023-06-15
    • ASP 对象与知識點问题:陷阱与挑战分析
      一、ASP 对象的陷阱 对象引用错误 对象引用错误是 ASP 中常见的陷阱之一,通常是由于对象未被正确初始化或释放导致的。例如: Set obj = Server.CreateObject("ADODB.Connection") o...
      99+
      2024-02-13
      ASP 对象 知识点 陷阱 挑战 解决方案
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作