首先,我们都知道,LinkedList数据结构是链表且是双向链表(每个节点会存储上个节点的地址、存储数据和下个节点的地址);
(图略微潦草,将就着看)
而ArrayList的数据存储结构则是数组,数组的优点就是有下标的同时其存储数据的内存空间是连续的,并且首元素内存地址即为数组的内存地址,就使得可以通过数学表达式计算出所需查下标的内存地址,不会像链表当检索某个数据时要从头节点一直往下查;而数组的缺点之一就是创建长度即是固定不可变的(类似于String,一旦赋值字符串在进行拼接就会重新字符串常量池创建新的字符串,原字符串还是存在的),
在看了源码的情况下得知,ArrayList的数组初始长度为10
然后就要说说这两种结构的集合是怎么进行操作数据的:
首先增加:
LinkedList
在LinkedList因为每个Node节点都有三个属性,分别存储前节点地址值、存储数据和后节点地址值(如果是头节点,上个节点地址值则为null,尾结点相反),所以当插入一条数据时,(因为链表正常添加数据的方式是尾插),其需将之前的尾结点的下一地址值(或修改其插入的前节点的存储空间的下个节点地址值和后节点存储空间的上个节点地址值进行修改)为当前数据空间的地址值,且将当且数据空间的上个节点地址值变为前节点地址值,数据空间的下个地址值设为null
ArrayList
底层是默认长度为10的数组,如果在未触发扩容机制(未到达原数组最大存储数据长度)前直接就往对应索引对应的存储空间存储,但是达到的数据长度,它底层就会进行创建新数组,新数组容量为原数组容量的1.5倍(也就是说删除或增加某个索引的话,就会使得部分下标左移或右移)
然后我们来看下测试代码
现在看下,1000条数据,ArrayList略胜一筹
再来看,10w条数据,链表效率就高出一截啦
经过多次测试,在1w3条数据左右,这两个集合在增加数据的效率就不相上下了,由此可得,正常增加数据的效率不一定肯定LinkedList快,而是要看数据的量级
再来分析删除的效率比较
LinkedList
前面有提到LinkedList的数据结构,增加和删除的操作基本一致,删除就是吧要删除的节点的地址位置在前节点的存储下个存储数据空间的地址值,改为被删除节点的后节点地址值,(后节点的操作同)
然后我们再来看看源码会更清晰
(先是判null值,如果要删除的值为null,原链表该是啥就还是啥,头节点还是头节点,尾结点就还是尾结点)
ArrayList
而相对于链表,ArrayList的删除就比较复杂了,它会先获得该值对应的索引(类似数组的下标),然后删除索引所在数据,将其索引后数据全部左移,最后末尾索引空间置为null
(同样先进行null判断)
显然ArrayList删除数据的步骤显然要比LinkedList看起来更为耗时,我们来看看测试用例
(LinkedList)
(ArrayList)
很明显,即使只删除集合中十分之一的数据,LinkedList都比ArrayList的效率要高的多
结论就是,LinkedList和ArrayList的增加在万级数据量才会比后者要快,而删除因为ArrayList对于删除数据的操作步骤要与之多的多,且更为耗时,所以存储同样数量数据的LinkedList会比ArrayList要更快。
(有兴趣的朋友也可以去写写这个demo,有什么意见或建议评论区欢迎探讨)