《数据结构》第九篇、java中ArrayList源码解析

机械师2.jpeg

引言

如题,为什么今天要给大家介绍java的中的ArrayList的源码呢?因为我毕竟是一个android开发工程师,不能一直给大家通过c语言讲解数据结构呀,java中也存在数据结构知识呢,我们的第7篇文章中介绍了下线性表中的顺序表,今天我们就来介绍一下java中的“顺序表的应用”,即ArrayList。

那大家大概猜到了,既然我说ArrayList是顺序表在Java中的应用,那么他内部是不是通过数组实现的呢?
你猜对了,就是通过数组实现的。

大致看下源码

我们来大致看下ArrayList的源码,这里我是通过Android studio看的,所以源码应该和java工程师用eclipse看的不太一样(有一些常量值可能不太一样),但是大体逻辑是类似的。
我贴张图,大家来感受一下:


Arraylist源码.png

我们看到,Arraylist源码有1476行,感觉是比较复杂的,而我们感兴趣的无非就是那么几种:

创建

添加元素

删除元素

清空列表

转成数组

所以,本篇文章就先从这几点入手,如果后续有朋友需要对其他操作解析讲解的话,可以私信我,我会再帮你分析一下的。

ArrayList的创建

先来看图


ArrayList创建.png

ArrayList创建提供了三个构造方法:

  • 带int 参数的构造方法
  • 无参构造方法
  • 带集合参数的构造方法
    我们先来看第一个

1、带int 参数的构造方法

带int参数的构造方法.png

其实大家看上方的英文注释就能明白一二了:
“这个构造方法指定了一个固定的容量,使用参数去设置Arraylist的容量大小”
所以说我们就可以这样去创建ArrayList:
ArrayList<String> list=new ArrayList<String>(5);
通过指定固定的大小去创建ArrayList。

但是,这样做就能够真的让ArrayList的容量是5了吗?我们来分析下


构造方法1.png

需要参考的值


构造方法1值.png

细看源码,是不是恍然大悟,原来集合内部有一个“内部数组"
elementData

看我们的注释,我们似乎猜对了,只要我们传入的容量值大于0,就能够设定固定容量的集合,如果传入的等于0,就直接用的是一个空的数组,如果小于0,则直接报错。


2、无参的构造方法

我们看过了有参的构造方法,其实再看无参的构造方法就觉得简单多了,来看一下吧:


构造方法2.png

需要参考的值


构造方法2值.png

”即复用了一个空的数组,这个数组和方法一种的数组是区分开的,区分开的目的是在进行第一个元素添加的时候计算需要扩充多大的容量。“
ok,其实我们常用的也就这样,直接new 出来
ArrayList<String> list=new ArrayList<String>();
所以我们这样写,跟我们直接指定大小容量的写现在看看应该没什么区别。


3、带collection参数的构造方法

构造方法三.png

"参数是一个带泛型的集合,该构造方法将会把参数中的元素放置到新创建的集合中去"
即通过这个方法我们可以获得跟传入集合一样的集合,里面的元素都是一模一样的,就是创建了个副本
解释一下
构造方法二解析.png

我们使用的时候就可以这样
构造方法3使用.png

得到list1的副本~~


ok,ArrayList的创建就先到这里,接下来我们看看ArrayList元素的添加

添加元素

两个.png

元素添加有两个方法,我们先看第一个

1、添加元素到结尾方法

元素添加1.png

”将元素添加到集合的最后位置“
解释一下

添加元素解释.png

我们看到,首先在添加元素的时候,做了一个扩容的操作我们点击进去看一下
扩容.png

我们看一下参考值
扩容参考值.png

接着,在扩容方法中又调用了一个”明确扩容的方法“:
明确扩容.png

紧接着,又调用了下grow方法,到这里grow才是真正的扩容方法了


真正的扩容方法.png

在扩容方法的最后,我们看到了数组复制的逻辑:


数组复制.png

但是我们接着点进去,看看真正的数组复制的方法
复制数组方法2.png

在进入System.arraycopy方法


真正数组复制的方法.png

因为add方法套的比较深了一点点,所以我画了张图,来看一下


java add流程.png

应该对你理解有点帮助吧~~

最终


把要插入元素添加到结尾.png

2、添加元素到指定位置

添加元素到指定位置.png

“把指定元素添加到集合的指定位置(将要插入元素位置之后的元素向后移动一个单位,然后将元素插入到中间)”
解释一下
插入元素到指定位置.png

我们看到,
1、首先做了一个参数校验,不允许插入索引大于集合的容量或者小于零,否则报数组越界异常。
2、跟上方的add(E element)方法一致,做扩容和复制的操作
3、这一点和add(E element)方法不一致,且比较关键,他的作用是将要插入元素位置之后的元素向后移动一个单位
4、在要插入的位置替换成要插入元素的值
5、增加集合长度


删除元素

删除元素两种.png

即一个是根据索引删除,一个是根据元素值删除
我们先来看根据索引删除的

1、根据索引删除元素

我们先看图

删除元素01.png

“将指定位置的元素删除,并且把删除位置后边的元素向左移动”
解释一下:
根据索引删除元素解释.png

比添加元素简单,因为不需要考虑到扩容问题
接着看

2、根据元素值删除元素

看源码:


根据元素值删除元素.png

“将第一次出现的对应元素值的元素删除掉,如果集合中没有这个元素值,集合将不会有所改变”
解释一下啦

根据元素值删除解释.png

我们看到上边有一个fastRemove方法,我们来看一下:
fastremove.png

我们看到,这个fastRemove方法和我们的根据索引删除方法很像
1、modCount++是计数单位,我们不做考虑
2、int numMoved=size-index-1;计算要移动的元素数量
3、移动元素
4、将结尾元素置为空。
所以其实根据元素值删除元素也是依据根据索引删除的。

清空集合

就是我们常用的clear方法,我们来看一下

清空集合.png

"移除集合中的所有元素,当处理结束后,这个集合就是一个空集合"
我们看步骤:
1、modCount++不需要考虑,跳过
2、循环数组,将每个元素置为空
3、改变集合长度为0
so easy!

转为数组

即我们常用的toArray方法


toarray.png

我们看到,有两个方法,一个无参,一个有参

1、无参toArray方法

无参toArray.png

“根据集合的顺序,返回一个包含所有元素的集合”
我们看到上边ArrayCopy应该就能想到上方我们添加元素那的操作了吧。操作是一致的,就是将集合中的数组的所有元素都复制到另外一个数组中,并且返回。
点进去看看:
toarray进入1.png

toarray进入2.png

就是将原来集合中的数组再进行了一次复制

2、有参toArray方法

有参toArray.png

"根据集合的顺序,返回一个包含所有元素的集合,这个集合是自己指定的,如果指定的这个集合有足够的空间,那么如果将所有元素复制进来的话,源集合尾元素将置为空"
解释一下:

有参toArray解释.png


总结,好了,今天介绍了也不少了,但是还有查找,替换这两个简单的操作还没有讲解到,不过看完今天的介绍,这两个操作对大家来说应该没什么问题了。不过有问题也可以私信我~~

谢谢大家关注~~~么么哒

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容