ArrayList底层实现原理

简介: ArrayList底层实现原理

上次咱们讲了常用的几个Map的原理,接下来咱们接着探讨下Map的兄弟,几个常用List的底层实现原理,首先要说的肯定是ArrayList吧,这用的多吧,来来来,上干货。


首先明确一点,Arraylist是基于动态数组实现的,就如同他名字一样,Array=数组,那动态数据是什么意思呢?我们都知道,数组一旦确定了大小是不可变的,动态数据说的通俗点就是可以变化长度的普通数组(其实底层实现还是数组,只不过用了复制转移等方法来实现数组长度变化),咱们接着看看Arraylist的底层数组到底是怎么操作的吧。


首先我们先看看Arraylist是怎么新加元素的吧add("111"),其实就是给数组里增加了一个元素,很简单如图:

插入元素呢add(2, "000"),我们基于数组实现的所以Arraylist是可以支持在指定下标插入元素的,整个过程是这样子的,比如我们要在数组下标2的位置插入一个000,他会首先把当前数组下标2位置以及之后的元素都往后面复制一遍(System.arraycopy方法),然后再把数组下标2的位置填上要插入的元素,底层的样子应该是这个样子的:

接着再来看看删除元素的时候是怎么操作的remove("333"),同样的道理在删除元素的下标位置之后的元素全部前移复制System.arraycopy方法最后一个元素会null,gc会把的null元素回收掉。

扩容呢,Arraylist如果初始不设置数组大小,默认的是10,当我们新增的数据超过10的时候就需要扩容,默认的扩容是1.5倍的扩容。细心的小伙伴又发现了,如果我本次存的数据是20大小怎么办,1.5倍=15不够了,是的没错,这里其实是个三目运算法,如果20大于15就取20作为这次扩容后的数组的大小,如果本次需要的小于15就取15作为本次扩容后的数组的大小,扩容完怎么办,要把原来数组里面的10个元素复制过来到新数组,就完了如图。

有人就问了,不能无限制的扩容吧,最大是多少,贴一段源码看看,第20行,当想扩容的大小.>最大数组长度,会调用一个hugeCapacity方法,用最小需要容量和最大数组长度比较,如果最小需要容量>最大数组长度则用Integer.MAX_VALUE作为数组长度,否则取最大数组长度作为新数组长度,有点绕,大家可以根据源码一起理解下。

Arraylist底层因为是数组,可以通过下标快速的访问查询等,但是,是不是发现问题了,每次插入元素,删除元素,或者扩容的时候,都要复制一波元素,是不是明白为啥说,删除,特殊点插入的效率就低,比较适合顺序添加、随机访问的场景这句话了。


再稍微扩展一点,有一个底层实现和Arraylist及其相似的Vector,只不过Arraylist是线程不安全的(可以把你的list变成List<String> synchronizedList = Collections.synchronizedList(list);来实现线程安全),方法都不是同步的,Vector线程安全的,主要的不同点就是这,还有个不同点是扩容不一样,一个是默认1.5倍,Vector是两倍。其他和LinkList的比较在下一篇文章里介绍。


最后,大家想获取更多知识的,可以继续关注公众号,不定时推送。分享了这么牛逼的知识,还不请小编喝个水吗,哈哈哈,欢迎土豪直接赏赞,谢谢,您的支持就是小编最大的动力。

相关文章
|
8月前
|
存储 算法 安全
HashMap底层实现原理
HashMap底层实现原理
101 0
|
8月前
|
存储 安全 Java
ConcurrentHashMap底层实现原理
ConcurrentHashMap底层实现原理
115 0
|
5月前
|
存储 Java 索引
深入学习Java集合之ArrayList的实现原理
深入学习Java集合之ArrayList的实现原理
31 0
|
6月前
|
存储 Cloud Native Linux
C++ list底层实现原理
C++ list底层实现原理
|
7月前
|
存储 算法 Java
java集合框架Map之HashMap底层原理解析
阈值(threshold) = 负载因子(loadFactor) x 容量(capacity) , 当HashMap中的table数组(桶)的长度 >= 阈值的时候就会自动触发扩容机制
45 0
|
11月前
|
存储 Java 程序员
ArrayList 的底层原理
ArrayList 是 Java 中常用的动态数组实现,它的底层是基于数组实现的。当创建一个 ArrayList 对象时,实际上是创建了一个 Object 类型的数组,初始容量为 10。当添加元素时,如果数组已满,ArrayList 会自动扩容,它会创建一个新的数组,并将原数组中的元素复制到新数组中。
906 0
ArrayList 的底层原理
|
存储 索引
ArrayList与LinkedList区别源码分析
1、ArrayList是基于数组,LinkedList是基于链表 2、基于数组的ArrayList对于根据索引值查找比较高效;基于链表的LinkedList对于增加、删除操作比较高效 3、剖析CRUD:
189 0
|
存储 安全 Java
ArrayList集合底层原理
ArrayList集合底层原理
|
存储 算法 Java
HashMap的底层实现原理及其一些常用方法的总结
首先,HashSet的底层实现就是map,接下来介绍一下HashMap的底层实现原理(以jdk7和jdk8为例),HashMap的一些常用方法我整理了一下,放到了文章结束的代码块里。 先介绍jdk7的: 当 HashMap map = new HashMap(); 实例化一个对象时,其底层实际上创建了一个Entry[ ] 类型的长度为16的数组。 然后,当你map.put(key,value);往map容器中添加对象时,底层会进行以下过程: ...
87 0
HashMap的底层实现原理及其一些常用方法的总结