第三次强调,ArrayLIst是一个普通的类

好,现在我们来讨论一下数组的删除,我们知道数组一但在堆内存中创建出来,数组长度是不可变的,看以下源码:

添加10个用户

比如我们要把“周八”这个人从数组中删除,如图:

我们只能循环数组,找到“周八“的下标5,由于数组没有提供删除方法,我们只能把下标为5的位置赋值为null(造成了数组空洞),“周八”这个Person对象已经没有引用指向它了,JVM的垃圾回收机制会在适当的时候回收它。但数组的长度还是10。下次当我们再循环查找某人时,稍不注意就会报空指针异常,虽然我们可以写非空去判断,但还是不太友好,我们把null后面的所有元素引用复制一下,往前拷贝一份,把null这个空给填上,如下图

复制后:

null之后的ref引用都按顺序复制了一份到原来的null的位置,原有的1引用被覆盖,但perArr[9]里的引用的指向还是不变(注意,是复制不是挪动,仔细看一下上面两个图)。
注意:perArr[8],perArr[9]指向的是同一个对象,这显然不是我们所要的结果,再处理一下,我们把perArr[9]的引用赋值为null。如下图:

问题似乎解决了,但数组长度还是10,还需要自行维护了一个size来记录长度,以上数组复制的代码,我们都要自己去写好在ArrayList这个类已经实现了,数组拷贝工作交给它就好,我们只需要调用ArrayList这个类提供的remove删除元素就行,至于底层数组怎么拷贝,元素怎么删除由ArrayList对象本身去搞定(面向对象的思想),我们来看一看ArrayList的两种元素删除方式,首先是按照下标删除:

我们先看看删除前的元素,debug一下:

perList里面已经有了10个元素,执行一下这两句remove操作,再看一下debug的情况

下标为5的“周八”已经删除掉了,下标为5以后的元素也按照我们之前的猜想往前移了一位,数组最后一个位置也置为null了。奇怪!“孙七”居然没有删掉!打印出来的个数也是9

我们看一下两种删除方式的源码。

基本上和我们图中的分析一致,并采用size来记录元素的真实个数,这段代码里还调了一个方法rangeCheck()方法,我们看一下:

好简单对不对,就是检查底层数组下标是否越界。我们再看另外一种删除方式

再看一下fastRemove()方法

和上面用下标删除方式一致,这儿就不细说了。

相信大家看到上面熟悉的equals()方法,就大概知道“孙七”为什么没有删掉了,如果你写了一个类(Person),你需要这个类完美的支持List,你必需按照List的规范来写代码,我们在
说说Java里的equals(中) - 知乎专栏 一文中已经说得很清楚了,这儿就不细说了。

知道问题的原因就好解决了,我们重写equals()方法试一下。

重写完equals方法,执行一下再debug看一下

孙七已经删除掉了,孙七后面的所有人也向前复制了一格,末位置为null,size也是8了,再画一画图:

图中的“孙七”,“周八”已经没有引用指向它们,JVM虚拟机会在适当的时候进行回收。

我们说一说ArrayList中删除元素的时间复杂度在ArrayLIst中,如果底层数组长度为n。

当我们用下标方式去删除元素时,如果删除的是最后一个元素,不会触发数组底层的复制,时间复杂度为O(1)。如果删除第i的元素,会触发底层数组复制n-i次,根据最坏情况,时间复杂度为O(n)。

由此看来,在ArrayList中删除指定元素的效率似乎不是太高,删除元素会造成底层数组复制,这个问题在LinkedList有方案解决,请关注后续专栏文章。

示例中,用对象的方式来删除元素,只是想告诉大家,这种删除方式是用equals方法来查找元素的下标进而删除的,实际工作中很少遇到需要new一个对象去删除的情况。不建议一上来就重写equals方法,除非你有特殊的需求。如果重写了equals方法,请一并重写hashCode方法,这个问题在说说Java里的equals(中)一文中已经说过了。

转载无限欢迎,但请注明「清浅池塘」和「https://zhuanlan.zhihu.com/p/27938717」。转载请在文中保留此段,感谢您对作者版权的尊重。如需商业转载或刊登,请联系作者获得授权。自助转载请点击:https://www.rightknights.com/materi

Arraylist理解(3)删除元素相关推荐

  1. ArrayList删除元素的细则

      删除ArrayList数组中某个元素,通常会使用for循环匹配目标元素完成删除操作. public void remove(List<String> list, String str) ...

  2. python里删除range里的数字_python中range函数与列表中删除元素

    一.range函数使用 range(1,5)   代表从1到4(不包含5),结果为:1,2,3,4   ,默认步长为1 range(1,5,2)   结果为:1, 3  (同样不包含5) ,步长为2 ...

  3. 浅谈为什么倒序遍历List删除元素没有问题

    要搞清楚这个问题,首先要知道如何正确的遍历List删除元素.注:下述代码完整版附在末尾. 先给出这次测试的list初始化结构: list.add("a");list.add(&qu ...

  4. Java中ArrayList问题:删除一个ArrayList中的重复元素,注意留意一个问题

    该问题有两种方法: 一 利用两个数组,此法简单,不讨论 二 利用一个数组,从第0个开始依次取元素,并在其后元素中查找是否有该元素,有则删掉后面的重复元素,依次遍历.---但是这种情况要特别注意,当后续 ...

  5. java arraylist 删除回车符_2种Java删除ArrayList中的重复元素的方法

    这篇文章将给出两种从ArrayList中删除重复元素的方法,分别是使用HashSet和LinkedHashSet. ArrayList是Java中最常用的集合类型之一.它允许灵活添加多个null元素, ...

  6. java arraylist 对象 删除_如何从Java中的ArrayList对象中删除冗余元素?

    接口集不允许重复的元素.茶add() 此接口的方法接受元素并添加到Set对象,如果添加成功,则如果您尝试使用此方法添加现有元素,则返回true,添加操作将返回false. 因此,要删除ArrayLis ...

  7. foreach迭代ArrayList时,真的不能删除元素吗?

    ArrayList是java开发时非常常用的类,常碰到需要对ArrayList循环删除元素的情况.这时候大家都不会使用foreach循环的方式来遍历List,因为它会抛java.util.Concur ...

  8. Java集合类ArrayList循环中删除特定元素

    在项目开发中,我们可能往往需要动态的删除ArrayList中的一些元素. 一种错误的方式: [java] view plain copy for(int i = 0 , len= list.size( ...

  9. 大剑无锋之ArrayList中使用增强for循环能删除元素吗?【面试推荐】

    好久没写java代码,前几天面试被问到不少java的问题,其中一个接下来要说的. 先看几段代码. 第一段(集合中两个元素,判断条件是第一个元素) ArrayList<String> lis ...

最新文章

  1. 2012组策略自动部署wsus
  2. MySQL FIND_IN_SET(s1,s2) 返回在字符串s2中与s1匹配的字符串的位置
  3. fasttext 文本分类_一文综述经典的深度文本分类方法
  4. 内容主题windows下简单的vbscript自动发送邮件--带附件
  5. 深度学习的实用层面 —— 1.12 梯度的数值逼近
  6. python 学习笔记(1)-转载
  7. 忽然发现自己少了很多爱好。。。。。。。。。
  8. InnerJoin分页导致的数据重复问题排查
  9. MATLAB安装破解教程(内涵所需文件)
  10. android 按钮边距,安卓button代码初始化默认内边距问题
  11. 软件性能测试模拟笔试题目
  12. 天梯L1-015 跟奥巴马一起画方块 (15 分)(Java)
  13. 三级分销系统要如何进行推广以及提升曝光度?
  14. 解决操作无法完成,因为其中的文件夹或文件已在另一程序中打开的问题
  15. vxworks6.6 ramdisk的创建
  16. 优秀班组长分享:生产车间管理技巧
  17. MyCat是什么?为什么要用MyCat?
  18. python timesleep单位_python的time.sleep()有多准确?
  19. Ubuntu下安装天翼3G客户端程序。
  20. linux设置双屏强制设置分辨率,话说你们的双屏显示器是怎样设置的 尤其是外接显示器分辨率设置...

热门文章

  1. CentOS配置本地YUM源
  2. 绑定方法与非绑定方法
  3. 对Url Schemes的简单了解
  4. PHP 截取字符串乱码的解决方案
  5. SpringCloud Alibaba-Nacos 的使用
  6. javascript获取系统时间时区_详解Linux操作系统修改时间和修改时区的方法
  7. 信息学奥赛一本通 1170:计算2的N次方 | OpenJudge NOI 1.6 12:计算2的N次方
  8. 信息学奥赛一本通 1023:Hello,World!的大小 | OpenJudge NOI 1.2 10
  9. 信息学奥赛一本通(2032:【例4.18】分解质因数)
  10. 马的遍历(洛谷-P1443)