ArrayList类源码浅析(一)
1、首先来看一下ArrayList类中的字段

可以看出,ArrayList维护了一个Object数组,默认容量是10,size记录数组的长度;
2、ArrayList提供了三个构造器:ArrayList(int initialCapacity),ArrayList(),ArrayList(Collection<? extends E> c)
带int参数的构造是指定ArrayList的大小,无参的构造函数,Object[]初始化为一个空数组,重点来讨论接受一个Colection参数的构造器,先看看源码

传入的Collection对象得到一个数组,赋值给elementData,然后再判断是否是Object[]类型,如果不是,则在copyOf方法里面生成一个Object[]数组,
返回并且赋值给elementData;Arrays.copyOf方法有多个重载方法,但是底层都是统一的调用System类中的arraycopy方法,这是一个系统的方法;
3、get(int index)、set(int index, E element)、remove(int index)方法

涉及到下标的操作,调用这三个方法,都会检查下标index是否合法,如果index>size,直接会抛出异常;
这两个方法都会调用一个公用的方法elementData(index),是根据下标index获取数组中的元素;
4、add(E e)、add(int index, E element)方法
在调用这两个方法的时候,都会调用ensureCapacityInternal(size + 1),来进行数组的扩容操作;
数组扩容分为两路:
1、如果是调用无参的构造函数创建的ArrayList对象,那么是第一次扩容,第一次扩容的数组大小为 final int DEFAULT_CAPACITY = 10;
2、如果ArrayList对象中数组已经存在,并且size+1超过了数组的长度,那么也需要进行数组的扩容;
这时因为elementData数组中已经有值,扩容时,数组长度增加为扩容之前的1.5倍,把原来数组的数据复制到新的数组中去;
这里就存在一个问题,如果频繁的去执行add操作,那么就会进行频繁的数组复制;
如果数组有100万个元素,那么就是有大量的是、内存复制操作,对于GC的压力会比较大,同时这个操作的效率也会非常低;
所以,必要的时候,可以指定数组的大小,使用ArrayList(int initialCapacity)构造方法去构造ArrayList对象,一定程度上能提高效率;


5、remove(Object o)这个方法可以看一下
这个方法是从ArrayList中删除一个元素,因为ArrayList里面可以存在null元素,所以在删除时,需要分开处理;
如果o为空,执行一个条件块,如果不为空执行另外一个条件块;
他们调用共用的删除方法:fastRemove(int index),这个方法在删除时,也是进行数组的复制;

ArrayList类源码浅析(一)的更多相关文章
- ArrayList类源码浅析(二)
1.removeAll(Collection<?> c)和retainAll(Collection<?> c)方法 第一个是从list中删除指定的匹配的集合元素,第二个方法是用 ...
- ArrayList类源码浅析(三)
1.看一个示例 运行上述代码,抛出一个异常: 这是一个典型的并发修改异常,如果把上述代码中的125行注释,把126行打开,运行就能通过了: 原因: 1)因为在迭代的时候,使用的是Itr类的对象,在调用 ...
- Long类源码浅析
1.Long类和Integer相类似,都是基本类型的包装类,类中的方法大部分都是类似的: 关于Integer类的浅析可以参看:Integer类源码浅析 2.这里主要介绍一下LongCache类,该缓存 ...
- [原创]Android系统中常用JAVA类源码浅析之HashMap
由于是浅析,所以我只分析常用的接口,注意是Android系统中的JAVA类,可能和JDK的源码有区别. 首先从构造函数开始, /** * Min capacity (other than zero) ...
- ArrayList类源码解析——ArrayList动态数组的实现细节(基于JDK8)
一.基本概念 ArrayList是一个可以添加对象元素,并进行元素的修改查询删除等操作的容器类.ArrayList底层是由数组实现的,所以和数组一样可以根据索引对容器对象所包含的元素进行快速随机的查询 ...
- java.lang.Byte 类源码浅析
Byte 类字节,属于Number. public final class Byte extends Number implements Comparable<Byte> { /** * ...
- LinkedList类源码浅析(一)
1.先来看一看LinkedList类的字段和构造方法 size记录链表的长度,first永远指向链表的第一个元素,last永远指向链表的最后一个元素 提供两个构造方法,一个无参的构造方法,一个接受一个 ...
- Integer类源码浅析
1.首先Integer提供了两类工具类,包括把一个int类型转成二进等, 其实执行转换算法只有一个方法: public static String toString(int i, int radix) ...
- LinkedList类源码浅析(二)
1.上一节介绍了LinkedList的几个基本的方法,其他方法类似,就不一一介绍: 现在再来看一个删除的方法:remove(Object o) remove方法接受一个Object参数,这里需要对参数 ...
随机推荐
- 如何快速的查找服务所在的进程id?
执行 pgrep -l 服务名称 这里以查找redis所在的进程id为例 执行 pgrep -l redis 从图中可知进程id 为30058
- 微信小程序 报错 “对应的服务器无效。控制台输入 showRequestInfo()可以获取更详细信息”
之前做的项目突然无法读出数据了,一测试发现报这个错误==>对应的服务器无效.控制台输入 showRequestInfo()可以获取更详细信息,后来发现是SSL证书到期了.重新申请了一个证书,免费 ...
- 2019 Multi-University Training Contest 8 - 1006 - Acesrc and Travel - 树形dp
http://acm.hdu.edu.cn/showproblem.php?pid=6662 仿照 CC B - TREE 那道题的思路写的,差不多.也是要走路径. 像这两种必须走到叶子的路径感觉是必 ...
- Codeforces 1209F. Koala and Notebook
传送门 考虑到达某个点时的数长度要尽量短,那么可以把边长看成此边十进制下的位数 那么对于最终答案我们只要考虑最短路 $DAG$ 上的情况 又发现其实边长都很小,所以可以暴力拆边,把边权都拆成 $1$, ...
- C++ new、delete、namespace关键字。
C++ 中的动态内存分配: C++与C语言分配内存关键字不同,C语言中的动态内存分配是通过 malloc(分配内存) 与 free(释放内存)完成.C++使用new(分配内存) delete(释放内 ...
- C#实现Web链接启动应用程序
C#实现Web链接启动应用程序 最近需要配合Web端实现用户点击链接来启动应用程序并且需要能够传参数给应用程序. 那么就可以使用注册表来实现这个功能 编写注册表可以在软件安装程序中加入,也可以在软件启 ...
- orm的设计思路
一,我们先搞懂什么是orm? ORM:对象关系映射(Object Relational Mapping,简称ORM),目的是想像操作对象一样操作数据库.因为数据库不是面向对象的,所以需要编程进行映射. ...
- 微信小程序实现滑动删除效果
在一些app中,随处可见左滑动的效果,在微信小程序中,官方并未提供相关组件,需要我们自己动手写一个类似的效果 下面仅列举出核心代码,具体的优化需要根据你自身的需求 <view class='li ...
- docker Dockerfile文件的编写部分命令
镜像的构建过程:编写dockerfile文件,执行docker build 进行构建镜像,最后docker run 运行容器镜像实例. docker build -t mycentos:1.01 . ...
- java学习笔记(5)多线程
一.简介(过段时间再写,多线程难度有点大) --------------------------------------- 1.进程:运行时的概念,运行的应用程序 2.线程:应用程序内部并发执行的代码 ...