ArrayList为什么查询速度快,增删速度慢

因为ArrayList底层是数组实现的,根据下标查询不需要比较,查询方式为,首地址+(元素长度*下标),基于这个位置读取相应的字节数就可以了,所以非常快;

增删会带来元素的移动,增加数据会向后移动,删除数据会向前移动,所以影响效率。

 

相反,在添加或删除数据的时候,LinkedList只需改变节点之间的引用关系,这就是LinkedList在添加和删除数据的时候通常比ArrayList要快的原因,

查询时通过二分法查找。

 

插入

LinkedList:

通过add(int index, E element)向LinkedList插入元素时。先是在双向链表中找到要插入节点的位置index;找到之后,再插入一个新节点
双向链表查找index位置的节点时,有一个加速动作若index < 双向链表长度的1/2,则从前向后查找; 否则,从后向前查找

 

ArrayList:

ensureCapacity(size+1) 的作用是“确认ArrayList的容量,若容量不够,则增加容量。
真正耗时的操作是 System.arraycopy(elementData, index, elementData, index + 1, size - index);

Sun JDK包的java/lang/System.java中的arraycopy()声明如下:

public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

arraycopy()是个JNI函数,它是在JVM中实现的。sunJDK中看不到源码,不过可以在OpenJDK包中看到的源码。网上有对arraycopy()的分析说明,请参考:System.arraycopy源码分析 
实际上,我们只需要了解: System.arraycopy(elementData, index, elementData, index + 1, size - index); 会移动index之后所有元素即可这就意味着,ArrayList的add(int index, E element)函数,会引起index之后所有元素的改变!

 

删除同插入原理

 

查询

LinkedList:通过get(int index)获取LinkedList第index个元素时先是在双向链表中找到要index位置的元素;找到之后再返回。
双向链表查找index位置的节点时,有一个加速动作若index < 双向链表长度的1/2,则从前向后查找; 否则,从后向前查找。

 

ArrayList:通过get(int index)获取ArrayList第index个元素时。直接返回数组中index位置的元素,而不需要像LinkedList一样进行查找。

 

posted @ 2021-03-15 14:31  节日快乐  阅读(3802)  评论(0编辑  收藏  举报