ArrayList和linkedList的插入、查找、删除

本文通过实验测试了ArrayList与LinkedList在添加、查找和删除操作上的性能表现,并对比了两种数据结构在不同数据量下的实际效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ArrayList是动态扩展的数组,LinkedList是双向链表的数据结构。

所以大多数人持有这样观点:

AL易于查找;有频繁的插入、删除使用AL不合适,因涉及到其他元素左右移动问题;

LL不易于查找;有频繁的插入、删除操作使用LL比较合适,因只涉及修改前后连接;

这里先不对以上观点给出我的结论,也没有非常仔细跟踪过java源码。这里给出一个测试样例及测试结果。测试结果的结论似乎不支持以上说法。当然,可能有涉及到测试样例的合理性、数据量是否足够大的问题,但个人认为这个例子还是合理的。大家有疑问的可以提出。欢迎大家多多交流。

@SuppressWarnings("all")
	static final class ArrayListAndLinkedArrayList{
		static final int N=100000;
	    static long timeList(List list){
	        long start=System.currentTimeMillis();
	        Object o = new Object();
	        for(int i=0;i<N;i++) {
	        	int id = (int) new java.util.Random().nextInt((i==0)?(i+1):i);
//	        	System.out.println(id);
	            list.add(id, o);
	        }
	        return System.currentTimeMillis()-start;
	    }
	    static long readList(List list){
	        long start=System.currentTimeMillis();
	        for(int i=0,j=list.size();i<j;i++){
	        	int id = (int) new java.util.Random().nextInt((i==0)?(i+1):i);
	        	list.get(id);
	        }
	        return System.currentTimeMillis()-start;
	    }

	    static List addList(List list){
	        Object o = new Object();
	        for(int i=0;i<N;i++) {
	        	int id = (int) new java.util.Random().nextInt((i==0)?(i+1):i);
	            list.add(id, o);
	        }
	        return list;
	    }
	    
	    static long removeList(List list){
	    	list=addList(list);
	    	long start=System.currentTimeMillis();
	        for(int i=0;i<N;i++) {
	        	int id = (int) new java.util.Random().nextInt((N-i)==0?(1):N-i);
	        	list.remove(id);
	        }
	        return System.currentTimeMillis()-start;
	    }
	    
	    public static void main(String[] args) {
	        System.out.println("ArrayList添加"+N+"条耗时:"+timeList(new ArrayList()));
	        System.out.println("LinkedList添加"+N+"条耗时:"+timeList(new LinkedList()));

	        List list1=addList(new ArrayList<>());
	        List list2=addList(new LinkedList<>());
	        System.out.println("ArrayList查找"+N+"条耗时:"+readList(list1));
	        System.out.println("LinkedList查找"+N+"条耗时:"+readList(list2));
	        
	        System.out.println("ArrayList删除"+N+"条耗时:"+removeList(new ArrayList()));
	        System.out.println("LinkedList删除"+N+"条耗时:"+removeList(new LinkedList()));
	        
	    }
	}


测试结果

100000条

ArrayList添加100000条耗时:1719
LinkedList添加100000条耗时:56433
ArrayList查找100000条耗时:22
LinkedList查找100000条耗时:4968
ArrayList删除100000条耗时:641
LinkedList删除100000条耗时:57121





5000条

ArrayList添加5000条耗时:25
LinkedList添加5000条耗时:77
ArrayList查找5000条耗时:5
LinkedList查找5000条耗时:136
ArrayList删除5000条耗时:13
LinkedList删除5000条耗时:62



当然,这里random会耗费一些时间,但这对两者是相等的,所以可以忽略。

以上的测试结果,似乎总是支持AL比LL的各方面都要好。


所以在这里大家可以探讨下这个问题:

AL易于查找;有频繁的插入、删除使用AL不合适,因涉及到其他元素左右移动问题;

LL不易于查找;有频繁的插入、删除操作使用LL比较合适,因只涉及修改前后连接;

还是

AL比LL的各方面都要好。







### Java 中 ArrayListLinkedList 插入删除操作性能比较 对于 `ArrayList` 而言,在列表中间执行插入或移除元素的操作效率较低。因为这些操作会触发数组内部元素的大规模移动来维持连续存储特性,时间复杂度为 O(n)[^1]。 相比之下,`LinkedList` 是基于双向链表实现的数据结构。这使得它在处理频繁的插入删除场景时表现更优,尤其是在已知位置的情况下。由于只需要调整相邻节点之间的指针而不需要搬移数据项,因此这类操作的时间复杂度可以达到 O(1),但前提是已经定位到目标节点的位置[^2]。 然而值得注意的是,如果要访问特定索引处的元素,则 `ArrayList` 显著优于 `LinkedList` 。因为在链表中查找指定下标的节点同样需要遍历整个链条直至找到对应位置,其平均情况下也需要 O(n) 时间开销;而对于数组来说,通过计算偏移量即可瞬间完成随机存取,即拥有常数级别的访问速度 O(1)。 综上所述: - 当涉及到大量顺序读写以及较少变动的情况时推荐使用 `ArrayList` - 如果应用程序涉及较多动态变化(特别是两端增删),则更适合选用 `LinkedList` 下面给出一段简单的测试代码用于对比两者在相同条件下进行多次插入后的耗时情况: ```java import java.util.ArrayList; import java.util.LinkedList; public class ListPerformanceTest { public static void main(String[] args) throws InterruptedException { int testSize = 100_000; // 测试样本大小 long startTime, endTime; // 对于 ArrayList插入测试 ArrayList<Integer> arrayList = new ArrayList<>(); startTime = System.currentTimeMillis(); for (int i = 0; i < testSize; ++i){ arrayList.add(i); } endTime = System.currentTimeMillis(); System.out.println("ArrayList insert time cost:"+(endTime-startTime)+"ms"); // 对于 LinkedList插入测试 LinkedList<Integer> linkedList = new LinkedList<>(); startTime = System.currentTimeMillis(); for (int i = 0; i < testSize; ++i){ linkedList.add(i); } endTime = System.currentTimeMillis(); System.out.println("LinkedList insert time cost:"+(endTime-startTime)+"ms"); } } ```
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值