源码解析:海量数据下,Arraylist为什么查询快,增删慢?LinkedList为什么增删快,查询慢?

关注公众号:”奇叔码技术“
回复:“java面试题大全”或者“java面试题”
即可领取资料

一、ArrayList和LinkedList中get()、add()、remove()解析时间复杂度快慢

1、Arraylist:

1、底层是数组数据结构,也就是说内存地址空间是连续的。

2、底层源码add方法中,我们发现如果为{}对象则进行默认扩容为10,如果大于10则进行位运算进行右移1位除以2再加上原来的默认容量10,就是扩容到1.5倍,为15.再判断如果减去15小于0,则把当前容量作为最大容量,如果减去Integer.size-8大于0则设置最大容量为Integer.MAX_VALUE。为2的31次方-1。最后再进行Arrays.copyof()的数据拷贝,底层C++源码是进行遍历然后指针引用向后移动。

3、底层源码remove方法,移除元素,底层C++源码是进行遍历然后指针引用向前移动,并且它不会缩容。

4、底层源码get方法,直接通过下标获取数据,时间复杂度为O(1),底层C++源码实现其实是,通过数组起始内存地址+数据类型的字节大小索引下标得到,例如100加上索引下标数据类型的字节大小 定位到起始位置,直接进行获取。


综上,Arraylist的get方法时间复杂度为O(1),增加和删除的时间复杂度由于扩容判断和数据拷贝所以比较慢。

2、LinkedList:

1、底层是双链表,也就是说内存空间可不连续。

2、底层源码get方法中,我们发现它是通过从头节点进行遍历,返回Node结点的item属性的数据。时间复杂度为O(n)。

2、底层源码add插入指定索引和数据的方法中,我们发现它是先判断头结点和尾结点哪个更近,然后从头结点或者尾结点进行遍历获取目标索引的Node结点,获取目标索引Node结点的prev结点,我们新new 一个Node结点

prev指向目标索引Node结点的prev结点、item为当前元素数据、next下一个节点指向目标索引Node结点,目标索引的Node结点的prev结点指向我们新创建的节点。目标索引的Node结点的prev如果是空则证明是第一个节点,新结点就是first结点。如果不是空则prev的next结点就指向新结点。

3、底层源码remove方法,跟add方法类似。


综上,LinkedList的get方法时间复杂度是O(n),增加和删除的时间复杂度比Arraylist的扩容判断和拷贝是相对比较快的。


综上,
在海量数据时,我们的arraylist的查询比链表快,因为内存地址连续。
在海量数据时,我们的LinkedList的add和remove 增加和删除快,虽说它有遍历,但它没有像arraylist那样会进行判断、扩容、数据拷贝的移动。所以快些。

二、ArrayList和LinkedList线程不安全如何解决?

1、ArrayList:

ArrayList是线程不安全的,方法没有进行synchronized同步修饰和lock使用。如果涉及多线程并发编程,需要线程安全可以使用Vector或者CopyOnWriteArrayList。

而CopyOnWriteArrayList的get方法没有加锁,add和remove都是用的JDK开发工具包的锁,公平锁ReentrantLock,lock方法和finally的unlock方法,

而Vector的get、add、remove都是用的java的锁,JVM实现的非公平锁synchronized

综上线程安全可以使用Vector或者CopyOnWriteArrayList中使用CopyOnWriteArrayList 效率更佳。

2、LinkedList:

linkedList如果需要线程安全则使用集合工具类

List  linkedList= Collections.synchronizedList(new LinkedList<>());

三、ArrayList和LinkedList的相同点

Arraylist和linkedList都秉属于List接口,都是有序的,可以存储重复元素。

四、最后!!!

点赞

评论

关注我

END
下篇来临!

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值