zoukankan      html  css  js  c++  java
  • ArrayList源代码深入剖析

    源码分析:

    对于ArrayList应该是开发当中每天都会与之打交道的,都知道它底层是由数组来实现的,但对于它底层的具体实现细节说实话却道不出一二来,所以打开它的源代码一探究竟,先来看一下应用代码:

    先查看一下它的类继承体系:

    比较复杂,接着根据咱们调用的是它的默认构造方法来初始化ArrayList的,所以看一下默认构造:

    好,接着咱们来往ArrayList集合中添加元素,其应用代码如下:

    所以从源码角度来看一下这个add的实现细节:

    看方法中的第一句:

    从英文的字面意思应该是确保集合的容量相关的东东,其中有一个size变量,先了解一下它:

    因为目前还木有元素当然size=0,所以ensureCapacity的参数为1,接着分析一下ensureCapacity的具体实现:

    接着判断minCapacity > oldCapacity是否满足,目前1 > 10条件不满足,也就不会执行条件里面的语句,然后方法返回到主流程:

    好!!如果add()了第10个元素,ensureCapacity(11),此时就会大于默认的10个长度的数组了,所以就会执行它里面的判断条件了,如下:

    那Arrays.copyOf()的具体作用是啥呢?它的总容量的个数会变成newCapacity个数了,但是前面的元素是之前元素elementData的内容,等于就是扩容了,原来只能容下10个元素,而这次扩容之后就变为16个元素了,前10个元素是之前的内容,而后面6个元素是空的元素。

    好~明白了add()方法之后,接下来在应用时会从集合中拿数据,所以会调用它:

    所以定位到该方法的源码:

    首先会做范围检查,这个比较好理解,如下:

    好,再回到主流程:

    嗯~~比较简单,接着再看一个新方法:

    明显比get()方法要复杂多了,下面一一分析:

    在返回之前还会做如下操作,这也是删除代码的核心逻辑:

    其实上面代码就是移位的操作,下面用图来表示一下:

    可见对于ArrayList的删除操作的代价是相当的高的。

     总结:

    • ArrayList底层采用数组实现,当使用不带参数的构造方法生成ArrayList对象时,实际上会在底层生成一个长度为10的Object类型的数组。
    • 如果增加的元素个数超过了10个,那么ArrayList底层会新生成一个数组,长度为原数组的1.5倍+1,然后将原数组的内容复制到新数组当中,并且后续增加的内容都会放到新数组当中,当新数组无法容纳增加的元素时,重复该过程。
    • 对于ArrayList元素的删除操作,需要将被删除元素的后续元素向前移动,代价比较高。
    • 集合当中只能放置对象的引用,无法放置原生数据类型,我们需要使用原生数据类型的包装类才能加入到集合当中。
    • 集合当中放置的都是Object类型,因此取出来的也是Object类型,那么必须要使用强制类型转换将其转换成真正的类型(放置进去的类型)。
  • 相关阅读:
    解决PKIX:unable to find valid certification path to requested target 的问题
    Linux 上的常用文件传输方式介绍与比较
    用VNC远程图形化连接Linux桌面的配置方法
    红帽中出现”This system is not registered with RHN”的解决方案
    linux安装时出现your cpu does not support long mode的解决方法
    CentOS SSH配置
    es6扩展运算符及rest运算符总结
    es6解构赋值总结
    tortoisegit安装、clon、推送
    es6环境搭建
  • 原文地址:https://www.cnblogs.com/webor2006/p/8994616.html
Copyright © 2011-2022 走看看