Java ArrayList实现的原理 LinkedList实现的原理

版权声明:本文为HCG原创文章,未经博主允许不得转载。请联系[email protected] https://blog.csdn.net/qq_39455116/article/details/82884667

ArrayList

  1. ArrayList是一个动态数组,
  2. 默认长度是10
  3. 需要保持的数据大于现有的容量时,开始扩容
  4. 如果扩为1.5倍还不满足需求,直接扩为你需要的大小
  5. ArrayList还给我们提供了将底层数组的容量调整为当前列表保存的实际元素的大小的功能。trimToSize()方法
  6. 采用的是 Arrays.copyOf浅复制,
这里简单说一下什么是浅复制

浅复制:只复制一个对象,但新对象和老对象同是一个地址值,

深复制:复制一个对象,新老对象的地址值也变了.

ArrayList使用一个内置的数组来存储元素,这个数组的起始容量是10.当数组需要增长时,新的容量按如下公式获得:新容量=(旧容量*3)/2+1,也就是说每一次容量大概会增长50%。这就意味着,如果你有一个包含大量元素的ArrayList对象,那么最终将有很大的空间会被浪费掉,这个浪费是由ArrayList的工作方式本身造成的。如果没有足够的空间来存放新的元素,数组将不得不被重新进行分配以便能够增加新的元素。对数组进行重新分配,将会导致性能急剧下降。如果我们知道一个ArrayList将会有多少个元素,我们可以通过构造方法来指定容量。
我们还可以通过trimToSize方法在ArrayList分配完毕之后去掉浪费掉的空间。

1. 数组的扩容是新建一个大容量(原始数组大小+扩充容量)的数组,然后将原始数组数据拷贝到新数组,然后将新数组作为扩容之后的数组。数组扩容的操作代价很高,如果容量过大,则会赋值最大的Interage值。我们应该尽量减少这种操作。

2. ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的CopyOnWriteArrayList类。


LinkedList

1、LinkedList是基于双向链表实现的,不论是增删改查方法还是队列和栈的实现,都可通过操作结点实现
2、LinkedList无需提前指定容量,因为基于链表操作,集合的容量随着元素的加入自动增加
3、LinkedList删除元素后集合占用的内存自动缩小,无需像ArrayList一样调用trimToSize()方法
4、LinkedList的所有方法没有进行同步,因此它也不是线程安全的,应该避免在多线程环境下使用

区别

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于双向链表的数据结构。

2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。

3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

4. ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间

5. 对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是统一的,分配一个内部Entry对象


猜你喜欢

转载自blog.csdn.net/qq_39455116/article/details/82884667
今日推荐